[PATCH v2 13/15] dmaengine: dw-axi-dmac: Add Intel KeemBay AxiDMA handshake
Add support for Intel KeemBay AxiDMA device handshake programming. Device handshake number passed in to the AxiDMA shall be written to the Intel KeemBay AxiDMA hardware handshake registers before DMA operations are started. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 52 +++ 1 file changed, 52 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 19806c586e81..0f40b41fd5c0 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -445,6 +445,48 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan) pm_runtime_put(chan->chip->dev); } +static int dw_axi_dma_set_hw_channel(struct axi_dma_chip *chip, u32 hs_number, +bool set) +{ + unsigned long start = 0; + unsigned long reg_value; + unsigned long reg_mask; + unsigned long reg_set; + unsigned long mask; + unsigned long val; + + if (!chip->apb_regs) + return -ENODEV; + + /* +* An unused DMA channel has a default value of 0x3F. +* 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 = hs_number; + } else { + reg_set = hs_number; + 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; + } + } + + return 0; +} + /* * If DW_axi_dmac sees CHx_CTL.ShadowReg_Or_LLI_Last bit of the fetched LLI * as 1, it understands that the current block is the final block in the @@ -725,6 +767,9 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr, llp = hw_desc->llp; } while (num_periods); + if (dw_axi_dma_set_hw_channel(chan->chip, chan->hw_hs_num, true)) + goto err_desc_get; + return vchan_tx_prep(&chan->vc, &desc->vd, flags); err_desc_get: @@ -851,6 +896,9 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, llp = hw_desc->llp; } while (sg_len); + if (dw_axi_dma_set_hw_channel(chan->chip, chan->hw_hs_num, true)) + goto err_desc_get; + return vchan_tx_prep(&chan->vc, &desc->vd, flags); err_desc_get: @@ -1019,6 +1067,10 @@ static int dma_chan_terminate_all(struct dma_chan *dchan) dev_warn(dchan2dev(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_hs_num, false); + spin_lock_irqsave(&chan->vc.lock, flags); vchan_get_all_descriptors(&chan->vc, &head); -- 2.18.0
[PATCH v2 11/15] dt-binding: dma: dw-axi-dmac: Add support for Intel KeemBay AxiDMA
Add support for Intel KeemBay AxiDMA to the dw-axi-dmac Schemas DT binding. Signed-off-by: Sia Jee Heng --- .../bindings/dma/snps,dw-axi-dmac.yaml| 25 +++ 1 file changed, 25 insertions(+) diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml index e688d25864bc..0e9bc5553a36 100644 --- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml +++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml @@ -8,6 +8,7 @@ title: Synopsys DesignWare AXI DMA Controller maintainers: - Eugeniy Paltsev description: | Synopsys DesignWare AXI DMA Controller DT Binding @@ -16,6 +17,7 @@ properties: compatible: enum: - snps,axi-dma-1.01a + - intel,kmb-axi-dma reg: items: @@ -24,6 +26,7 @@ properties: reg-names: items: - const: axidma_ctrl_regs + - const: axidma_apb_regs interrupts: maxItems: 1 @@ -122,3 +125,25 @@ examples: snps,priority = <0 1 2 3>; snps,axi-max-burst-len = <16>; }; + + - | + #include + #include + /* example with intel,kmb-axi-dma */ + #define KEEM_BAY_PSS_AXI_DMA + #define KEEM_BAY_PSS_APB_AXI_DMA + axi_dma: dma@2800 { + compatible = "intel,kmb-axi-dma"; + reg = <0x2800 0x1000 0x2025 0x24>; + reg-names = "axidma_ctrl_regs", "axidma_apb_regs"; + interrupts = ; + clock-names = "core-clk", "cfgr-clk"; + clocks = <&scmi_clk KEEM_BAY_PSS_AXI_DMA>, <&scmi_clk KEEM_BAY_PSS_APB_AXI_DMA>; + #dma-cells = <1>; + dma-channels = <8>; + snps,dma-masters = <1>; + snps,data-width = <4>; + snps,priority = <0 0 0 0 0 0 0 0>; + snps,block-size = <1024 1024 1024 1024 1024 1024 1024 1024>; + snps,axi-max-burst-len = <16>; + }; -- 2.18.0
[PATCH v2 10/15] dmaengine: dw-axi-dmac: Add Intel KeemBay AxiDMA support
Add support for Intel KeemBay AxiDMA to the .compatible field. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 1 + 1 file changed, 1 insertion(+) 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 cd99557a716c..ce89b4dee1dc 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -1396,6 +1396,7 @@ static const struct dev_pm_ops dw_axi_dma_pm_ops = { static const struct of_device_id dw_dma_of_id_table[] = { { .compatible = "snps,axi-dma-1.01a" }, + { .compatible = "intel,kmb-axi-dma" }, {} }; MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); -- 2.18.0
[PATCH v2 12/15] dmaengine: dw-axi-dmac: Add Intel KeemBay DMA register fields
Add support for Intel KeemBay DMA registers. These registers are required to run data transfer between device to memory and memory to device on Intel KeemBay SoC. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 14 ++ 2 files changed, 18 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 ce89b4dee1dc..19806c586e81 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -1252,6 +1252,10 @@ static int dw_probe(struct platform_device *pdev) if (IS_ERR(chip->regs)) return PTR_ERR(chip->regs); + chip->apb_regs = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(chip->apb_regs)) + dev_warn(&pdev->dev, "apb_regs not supported\n"); + chip->core_clk = devm_clk_get(chip->dev, "core-clk"); if (IS_ERR(chip->core_clk)) return PTR_ERR(chip->core_clk); diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index bdb66d775125..f64e8d33b127 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -63,6 +63,7 @@ struct axi_dma_chip { struct device *dev; int irq; void __iomem*regs; + void __iomem*apb_regs; struct clk *core_clk; struct clk *cfgr_clk; struct dw_axi_dma *dw; @@ -169,6 +170,19 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan) #define CH_INTSIGNAL_ENA 0x090 /* R/W Chan Interrupt Signal Enable */ #define CH_INTCLEAR0x098 /* W Chan Interrupt Clear */ +/* Apb slave registers */ +#define DMAC_APB_CFG 0x000 /* DMAC Apb Configuration Register */ +#define DMAC_APB_STAT 0x004 /* DMAC Apb Status Register */ +#define DMAC_APB_DEBUG_STAT_0 0x008 /* DMAC Apb Debug Status Register 0 */ +#define DMAC_APB_DEBUG_STAT_1 0x00C /* DMAC Apb Debug Status Register 1 */ +#define DMAC_APB_HW_HS_SEL_0 0x010 /* DMAC Apb HW HS register 0 */ +#define DMAC_APB_HW_HS_SEL_1 0x014 /* DMAC Apb HW HS register 1 */ +#define DMAC_APB_LPI 0x018 /* DMAC Apb Low Power Interface Reg */ +#define DMAC_APB_BYTE_WR_CH_EN 0x01C /* DMAC Apb Byte Write Enable */ +#define DMAC_APB_HALFWORD_WR_CH_EN 0x020 /* DMAC Halfword write enables */ + +#define UNUSED_CHANNEL 0x3F /* Set unused DMA channel to 0x3F */ +#define MAX_BLOCK_SIZE 0x1000 /* 1024 blocks * 4 bytes data width */ /* DMAC_CFG */ #define DMAC_EN_POS0 -- 2.18.0
[PATCH v2 15/15] dmaengine: dw-axi-dmac: Set constraint to the Max segment size
Add support for DMA Scatter-Gather (SG) constraint so that DMA clients can handle the AxiDMA limitation. Without supporting DMA constraint the default Max segment size reported by dmaengine is 64KB, which is not supported by Intel KeemBay AxiDMA. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 8 drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + 2 files changed, 9 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 d4fca3ffe67f..bd56e21663c3 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1407,6 +1408,13 @@ static int dw_probe(struct platform_device *pdev) dw->dma.device_prep_slave_sg = dw_axi_dma_chan_prep_slave_sg; dw->dma.device_prep_dma_cyclic = dw_axi_dma_chan_prep_cyclic; + /* +* Synopsis DesignWare AxiDMA datasheet mentioned Maximum +* supported blocks is 1024. Device register width is 4 bytes. +* Therefore, set constraint to 1024 * 4. +*/ + dw->dma.dev->dma_parms = &dw->dma_parms; + dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE); platform_set_drvdata(pdev, chip); pm_runtime_enable(chip->dev); diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index f64e8d33b127..67669049cead 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -54,6 +54,7 @@ struct axi_dma_chan { struct dw_axi_dma { struct dma_device dma; struct dw_axi_dma_hcfg *hdata; + struct device_dma_parametersdma_parms; /* channels */ struct axi_dma_chan *chan; -- 2.18.0
[PATCH v2 14/15] dmaengine: dw-axi-dmac: Add Intel KeemBay AxiDMA BYTE and HALFWORD registers
Add support for Intel KeemBay AxiDMA BYTE and HALFWORD registers programming. Intel KeemBay AxiDMA supports data transfer between device to memory and memory to device operations. This code is needed by I2C, I3C, I2S, SPI and UART which uses FIFO size of 8bits and 16bits to perform memory to device data transfer operation. 0-padding functionality is provided to avoid pre-processing of data on CPU. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 44 --- 1 file changed, 39 insertions(+), 5 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 0f40b41fd5c0..d4fca3ffe67f 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -312,7 +312,7 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan, struct axi_dma_desc *first) { u32 priority = chan->chip->dw->hdata->priority[chan->id]; - u32 reg, irq_mask; + u32 reg, irq_mask, reg_width, offset, val; u8 lms = 0; /* Select AXI0 master for LLI fetching */ if (unlikely(axi_chan_is_hw_enable(chan))) { @@ -334,6 +334,25 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan, DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_SRC_POS); switch (chan->direction) { case DMA_MEM_TO_DEV: + if (chan->chip->apb_regs) { + reg_width = __ffs(chan->config.dst_addr_width); + /* +* Configure Byte and Halfword register +* for MEM_TO_DEV only. +*/ + if (reg_width == DWAXIDMAC_TRANS_WIDTH_16) { + offset = DMAC_APB_HALFWORD_WR_CH_EN; + val = ioread32(chan->chip->apb_regs + offset); + val |= BIT(chan->id); + iowrite32(val, chan->chip->apb_regs + offset); + } else if (reg_width == DWAXIDMAC_TRANS_WIDTH_8) { + offset = DMAC_APB_BYTE_WR_CH_EN; + val = ioread32(chan->chip->apb_regs + offset); + val |= BIT(chan->id); + iowrite32(val, chan->chip->apb_regs + offset); + } + } + reg |= (chan->config.device_fc ? DWAXIDMAC_TT_FC_MEM_TO_PER_DST : DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC) @@ -1054,8 +1073,9 @@ static int dma_chan_terminate_all(struct dma_chan *dchan) { struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); u32 chan_active = BIT(chan->id) << DMAC_CHAN_EN_SHIFT; + u32 reg_width = __ffs(chan->config.dst_addr_width); unsigned long flags; - u32 val; + u32 offset, val; int ret; LIST_HEAD(head); @@ -1067,9 +1087,23 @@ static int dma_chan_terminate_all(struct dma_chan *dchan) dev_warn(dchan2dev(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_hs_num, false); + if (chan->direction != DMA_MEM_TO_MEM) { + ret = dw_axi_dma_set_hw_channel(chan->chip, + chan->hw_hs_num, false); + if (ret == 0 && chan->direction == DMA_MEM_TO_DEV) { + if (reg_width == DWAXIDMAC_TRANS_WIDTH_8) { + offset = DMAC_APB_BYTE_WR_CH_EN; + val = ioread32(chan->chip->apb_regs + offset); + val &= ~BIT(chan->id); + iowrite32(val, chan->chip->apb_regs + offset); + } else if (reg_width == DWAXIDMAC_TRANS_WIDTH_16) { + offset = DMAC_APB_HALFWORD_WR_CH_EN; + val = ioread32(chan->chip->apb_regs + offset); + val &= ~BIT(chan->id); + iowrite32(val, chan->chip->apb_regs + offset); + } + } + } spin_lock_irqsave(&chan->vc.lock, flags); -- 2.18.0
Re: [PATCH] printf: fix Woverride-init warning for EDEADLK errno
Good morning Arnd, On 10/26/20 10:49 PM, Arnd Bergmann wrote: > From: Arnd Bergmann > > On most architectures, gcc -Wextra warns about the list of error > numbers containing both EDEADLK and EDEADLOCK: > > lib/errname.c:15:67: warning: initialized field overwritten [-Woverride-init] >15 | #define E(err) [err + BUILD_BUG_ON_ZERO(err <= 0 || err > 300)] = "-" > #err > | ^~~ > lib/errname.c:172:2: note: in expansion of macro 'E' > 172 | E(EDEADLK), /* EDEADLOCK */ > | ^ > lib/errname.c:15:67: note: (near initialization for 'names_0[35]') >15 | #define E(err) [err + BUILD_BUG_ON_ZERO(err <= 0 || err > 300)] = "-" > #err > | ^~~ > lib/errname.c:172:2: note: in expansion of macro 'E' > 172 | E(EDEADLK), /* EDEADLOCK */ > | ^ bad performance of gcc to warn twice about the same line and not mentioning the line that has E(EDEADLOCK). > Make that line conditional on the two values being distinct. > > Fixes: 57f5677e535b ("printf: add support for printing symbolic error names") > Signed-off-by: Arnd Bergmann > --- > lib/errname.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/lib/errname.c b/lib/errname.c > index 0c4d3e66170e..6adff0bf2445 100644 > --- a/lib/errname.c > +++ b/lib/errname.c > @@ -169,7 +169,9 @@ static const char *names_0[] = { > E(ECANCELED), /* ECANCELLED */ > E(EAGAIN), /* EWOULDBLOCK */ > E(ECONNREFUSED), /* EREFUSED */ > +#if EDEADLK != EDEADLOCK > E(EDEADLK), /* EDEADLOCK */ > +#endif The comments suggest that duplicates are expected. Would it make sense to add similar conditions to the other three entries? Best regards Uwe > }; > #undef E > signature.asc Description: OpenPGP digital signature
[PATCH v2 06/15] dmaengine: dw-axi-dmac: Support device_prep_slave_sg
Add device_prep_slave_sg() callback function so that DMA_MEM_TO_DEV and DMA_DEV_TO_MEM operations in single mode can be supported. Existing AxiDMA driver only support data transfer between memory to memory. Data transfer between device to memory and memory to device in single mode would failed if this interface is not supported by the AxiDMA driver. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 142 ++ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + 2 files changed, 143 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 16e6934ae9a1..1124c97025f2 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -307,6 +307,22 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan, priority << CH_CFG_H_PRIORITY_POS | DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_DST_POS | DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_SRC_POS); + switch (chan->direction) { + case DMA_MEM_TO_DEV: + reg |= (chan->config.device_fc ? + DWAXIDMAC_TT_FC_MEM_TO_PER_DST : + DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC) + << CH_CFG_H_TT_FC_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; + break; + default: + break; + } axi_chan_iowrite32(chan, CH_CFG_H, reg); write_chan_llp(chan, first->hw_desc[0].llp | lms); @@ -559,6 +575,129 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, return NULL; } +static struct dma_async_tx_descriptor * +dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, + unsigned int sg_len, + enum dma_transfer_direction direction, + unsigned long flags, void *context) +{ + struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); + unsigned int data_width = BIT(chan->chip->dw->hdata->m_data_width); + struct axi_dma_hw_desc *hw_desc = NULL; + struct axi_dma_desc *desc = NULL; + struct scatterlist *sg; + unsigned int reg_width; + unsigned int mem_width; + dma_addr_t reg; + unsigned int i; + u32 ctllo, ctlhi; + size_t block_ts; + u32 mem, len; + u64 llp = 0; + u8 lms = 0; /* Select AXI0 master for LLI fetching */ + + if (unlikely(!is_slave_direction(direction) || !sg_len)) + return NULL; + + chan->direction = direction; + + desc = axi_desc_alloc(sg_len); + if (unlikely(!desc)) + goto err_desc_get; + + switch (direction) { + case DMA_MEM_TO_DEV: + reg_width = __ffs(chan->config.dst_addr_width); + reg = chan->config.dst_addr; + ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS | + DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS | + DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS; + break; + case DMA_DEV_TO_MEM: + reg_width = __ffs(chan->config.src_addr_width); + reg = chan->config.src_addr; + ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS | + DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS | + DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS; + break; + default: + return NULL; + } + + desc->chan = chan; + + for_each_sg(sgl, sg, sg_len, i) { + mem = sg_dma_address(sg); + len = sg_dma_len(sg); + hw_desc = &desc->hw_desc[i]; + mem_width = __ffs(data_width | mem | len); + if (mem_width > DWAXIDMAC_TRANS_WIDTH_32) + mem_width = DWAXIDMAC_TRANS_WIDTH_32; + + hw_desc->lli = axi_desc_get(chan, &hw_desc->llp); + if (unlikely(!hw_desc->lli)) + goto err_desc_get; + + if (direction == DMA_MEM_TO_DEV) + block_ts = len >> mem_width; + else + block_ts = len >> reg_width; + + ctlhi = CH_CTL_H_LLI_VALID; + if (chan->chip->dw->hdata->restrict_axi_burst_len) { + u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len; + + ctlhi |= (CH_CTL_H_ARLEN_EN | + burst_len << CH_CTL_H_ARLEN_POS | + CH_CTL_H_AWLEN_EN | + burst_len << CH_CTL_H_AWLEN_POS); +
[PATCH v2 07/15] dmaegine: dw-axi-dmac: Support device_prep_dma_cyclic()
Add support for device_prep_dma_cyclic() callback function to benefit DMA cyclic client, for example ALSA. Existing AxiDMA driver only support data transfer between memory to memory. Data transfer between device to memory and memory to device in cyclic mode would failed if this interface is not supported by the AxiDMA driver. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 182 +- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 + 2 files changed, 177 insertions(+), 7 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 1124c97025f2..9e574753aaf0 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -575,6 +577,135 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, return NULL; } +static struct dma_async_tx_descriptor * +dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr, + size_t buf_len, size_t period_len, + enum dma_transfer_direction direction, + unsigned long flags) +{ + struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); + u32 data_width = BIT(chan->chip->dw->hdata->m_data_width); + struct axi_dma_hw_desc *hw_desc = NULL; + struct axi_dma_desc *desc = NULL; + dma_addr_t src_addr = dma_addr; + u32 num_periods = buf_len / period_len; + unsigned int reg_width; + unsigned int mem_width; + dma_addr_t reg; + unsigned int i; + u32 ctllo, ctlhi; + size_t block_ts; + u64 llp = 0; + u8 lms = 0; /* Select AXI0 master for LLI fetching */ + + block_ts = chan->chip->dw->hdata->block_size[chan->id]; + + mem_width = __ffs(data_width | dma_addr | period_len); + if (mem_width > DWAXIDMAC_TRANS_WIDTH_32) + mem_width = DWAXIDMAC_TRANS_WIDTH_32; + + desc = axi_desc_alloc(num_periods); + if (unlikely(!desc)) + goto err_desc_get; + + chan->direction = direction; + desc->chan = chan; + chan->cyclic = true; + + switch (direction) { + case DMA_MEM_TO_DEV: + reg_width = __ffs(chan->config.dst_addr_width); + reg = chan->config.dst_addr; + ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS | + DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS | + DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS; + break; + case DMA_DEV_TO_MEM: + reg_width = __ffs(chan->config.src_addr_width); + reg = chan->config.src_addr; + ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS | + DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS | + DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS; + break; + default: + return NULL; + } + + for (i = 0; i < num_periods; i++) { + hw_desc = &desc->hw_desc[i]; + + hw_desc->lli = axi_desc_get(chan, &hw_desc->llp); + if (unlikely(!hw_desc->lli)) + goto err_desc_get; + + if (direction == DMA_MEM_TO_DEV) + block_ts = period_len >> mem_width; + else + block_ts = period_len >> reg_width; + + ctlhi = CH_CTL_H_LLI_VALID; + if (chan->chip->dw->hdata->restrict_axi_burst_len) { + u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len; + + ctlhi |= (CH_CTL_H_ARLEN_EN | + burst_len << CH_CTL_H_ARLEN_POS | + CH_CTL_H_AWLEN_EN | + burst_len << CH_CTL_H_AWLEN_POS); + } + + hw_desc->lli->ctl_hi = cpu_to_le32(ctlhi); + + if (direction == DMA_MEM_TO_DEV) + ctllo |= mem_width << CH_CTL_L_SRC_WIDTH_POS; + else + ctllo |= mem_width << CH_CTL_L_DST_WIDTH_POS; + + if (direction == DMA_MEM_TO_DEV) { + write_desc_sar(hw_desc, src_addr); + write_desc_dar(hw_desc, reg); + } else { + write_desc_sar(hw_desc, reg); + write_desc_dar(hw_desc, src_addr); + } + + hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1); + + ctllo |= (DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | + DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS); + hw_desc->lli->ctl_lo = cpu_to_le32(ctllo); + + set_desc_src_master
[PATCH v2 05/15] dmaengine: dw-axi-dmac: Add device_config operation
Add device_config() callback function so that the device address can be passed to the dma driver. DMA clients use this interface to pass in the device address to the AxiDMA. Without this interface, data transfer between device to memory and memory to device would failed. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 11 +++ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + 2 files changed, 12 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 56b213211341..16e6934ae9a1 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -559,6 +559,16 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, return NULL; } +static int dw_axi_dma_chan_slave_config(struct dma_chan *dchan, + struct dma_slave_config *config) +{ + struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); + + memcpy(&chan->config, config, sizeof(*config)); + + return 0; +} + static void axi_chan_dump_lli(struct axi_dma_chan *chan, struct axi_dma_hw_desc *desc) { @@ -948,6 +958,7 @@ static int dw_probe(struct platform_device *pdev) dw->dma.device_prep_dma_memcpy = dma_chan_prep_dma_memcpy; dw->dma.device_synchronize = dw_axi_dma_synchronize; + dw->dma.device_config = dw_axi_dma_chan_slave_config; platform_set_drvdata(pdev, chip); diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index f886b2bb75de..a75b921d6b1a 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -43,6 +43,7 @@ struct axi_dma_chan { struct virt_dma_chanvc; struct axi_dma_desc *desc; + struct dma_slave_config config; /* these other elements are all protected by vc.lock */ boolis_paused; }; -- 2.18.0
[PATCH v2 02/15] dmaengine: dw-axi-dmac: simplify descriptor management
Simplify and refactor the descriptor management by removing the redundant Linked List Item (LLI) queue control logic from the AxiDMA driver. The descriptor is split into virtual descriptor and hardware LLI so that only hardware LLI memories are allocated from the DMA memory pool. Up to 64 descriptors can be allocated within a PAGE_SIZE compare to 16 descriptors in previous version. This solves the problem where an ALSA driver expects more than 16 DMA descriptors to run. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 164 ++ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 9 +- 2 files changed, 102 insertions(+), 71 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 14c1ac26f866..8cfd645479e1 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "dw-axi-dmac.h" @@ -195,43 +196,58 @@ static inline const char *axi_chan_name(struct axi_dma_chan *chan) return dma_chan_name(&chan->vc.chan); } -static struct axi_dma_desc *axi_desc_get(struct axi_dma_chan *chan) +static struct axi_dma_desc *axi_desc_alloc(u32 num) { - struct dw_axi_dma *dw = chan->chip->dw; struct axi_dma_desc *desc; + + desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + if (!desc) + return NULL; + + desc->hw_desc = kcalloc(num, sizeof(*desc->hw_desc), GFP_NOWAIT); + if (!desc->hw_desc) { + kfree(desc); + return NULL; + } + + return desc; +} + +static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan, + dma_addr_t *addr) +{ + struct dw_axi_dma *dw = chan->chip->dw; + struct axi_dma_lli *lli; dma_addr_t phys; - desc = dma_pool_zalloc(dw->desc_pool, GFP_NOWAIT, &phys); - if (unlikely(!desc)) { + lli = dma_pool_zalloc(dw->desc_pool, GFP_NOWAIT, &phys); + if (unlikely(!lli)) { dev_err(chan2dev(chan), "%s: not enough descriptors available\n", axi_chan_name(chan)); return NULL; } atomic_inc(&chan->descs_allocated); - INIT_LIST_HEAD(&desc->xfer_list); - desc->vd.tx.phys = phys; - desc->chan = chan; + *addr = phys; - return desc; + return lli; } static void axi_desc_put(struct axi_dma_desc *desc) { struct axi_dma_chan *chan = desc->chan; struct dw_axi_dma *dw = chan->chip->dw; - struct axi_dma_desc *child, *_next; - unsigned int descs_put = 0; + int count = atomic_read(&chan->descs_allocated); + struct axi_dma_hw_desc *hw_desc; + int descs_put; - list_for_each_entry_safe(child, _next, &desc->xfer_list, xfer_list) { - list_del(&child->xfer_list); - dma_pool_free(dw->desc_pool, child, child->vd.tx.phys); - descs_put++; + for (descs_put = 0; descs_put < count; descs_put++) { + hw_desc = &desc->hw_desc[descs_put]; + dma_pool_free(dw->desc_pool, hw_desc->lli, hw_desc->llp); } - dma_pool_free(dw->desc_pool, desc, desc->vd.tx.phys); - descs_put++; - + kfree(desc->hw_desc); + kfree(desc); atomic_sub(descs_put, &chan->descs_allocated); dev_vdbg(chan2dev(chan), "%s: %d descs put, %d still allocated\n", axi_chan_name(chan), descs_put, @@ -258,9 +274,9 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, return ret; } -static void write_desc_llp(struct axi_dma_desc *desc, dma_addr_t adr) +static void write_desc_llp(struct axi_dma_hw_desc *desc, dma_addr_t adr) { - desc->lli.llp = cpu_to_le64(adr); + desc->lli->llp = cpu_to_le64(adr); } static void write_chan_llp(struct axi_dma_chan *chan, dma_addr_t adr) @@ -295,7 +311,7 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan, DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_SRC_POS); axi_chan_iowrite32(chan, CH_CFG_H, reg); - write_chan_llp(chan, first->vd.tx.phys | lms); + write_chan_llp(chan, first->hw_desc[0].llp | lms); irq_mask = DWAXIDMAC_IRQ_DMA_TRF | DWAXIDMAC_IRQ_ALL_ERR; axi_chan_irq_sig_set(chan, irq_mask); @@ -378,67 +394,78 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan) * transfer and completes the DMA transfer operation at the end of current * block transfer. */ -static void set_desc_last(struct axi_dma_desc *desc) +static void set_desc_last(struct axi_dma_hw_desc *desc) { u32 val; - val = le32_to_cpu(desc->lli.ctl_hi); + val = le32_to_cpu(desc->lli->ctl_hi); val |= CH_CTL_H_LLI_LAST; - desc->lli.ctl_hi = cpu_to_le32(val); + desc->lli->
[PATCH v2 08/15] dmaengine: dw-axi-dmac: Support of_dma_controller_register()
Add support for of_dma_controller_register() so that DMA clients can pass in device handshake number to the AxiDMA driver. DMA clients shall code the device handshake number in the Device tree. When DMA activities are needed, DMA clients shall invoke OF helper function to pass in the device handshake number to the AxiDMA. Without register to the of_dma_controller_register(), data transfer between memory to device and device to memory operations would failed. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 26 +++ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 + 2 files changed, 27 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 9e574753aaf0..011cf7134f25 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1103,6 +1104,22 @@ static int __maybe_unused axi_dma_runtime_resume(struct device *dev) return axi_dma_resume(chip); } +static struct dma_chan *dw_axi_dma_of_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct dw_axi_dma *dw = ofdma->of_dma_data; + struct axi_dma_chan *chan; + struct dma_chan *dchan; + + dchan = dma_get_any_slave_channel(&dw->dma); + if (!dchan) + return NULL; + + chan = dchan_to_axi_dma_chan(dchan); + chan->hw_hs_num = dma_spec->args[0]; + return dchan; +} + static int parse_device_properties(struct axi_dma_chip *chip) { struct device *dev = chip->dev; @@ -1292,6 +1309,13 @@ static int dw_probe(struct platform_device *pdev) if (ret) goto err_pm_disable; + /* Register with OF helpers for DMA lookups */ + ret = of_dma_controller_register(pdev->dev.of_node, +dw_axi_dma_of_xlate, dw); + if (ret < 0) + dev_warn(&pdev->dev, +"Failed to register OF DMA controller, fallback to MEM_TO_MEM mode\n"); + dev_info(chip->dev, "DesignWare AXI DMA Controller, %d channels\n", dw->hdata->nr_channels); @@ -1325,6 +1349,8 @@ static int dw_remove(struct platform_device *pdev) devm_free_irq(chip->dev, chip->irq, chip); + of_dma_controller_free(chip->dev->of_node); + list_for_each_entry_safe(chan, _chan, &dw->dma.channels, vc.chan.device_node) { list_del(&chan->vc.chan.device_node); diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index a26b0a242a93..651874e5c88f 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -37,6 +37,7 @@ struct axi_dma_chan { struct axi_dma_chip *chip; void __iomem*chan_regs; u8 id; + u8 hw_hs_num; atomic_tdescs_allocated; struct dma_pool *desc_pool; -- 2.18.0
[PATCH v2 03/15] dmaengine: dw-axi-dmac: move dma_pool_create() to alloc_chan_resources()
The DMA memory block is created at driver load time and exist for device lifetime. Move the dma_pool_create() to the ->chan_resource() callback function allowing the DMA memory blocks to be created as needed and destroyed when the channel is freed. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 24 ++- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 +- 2 files changed, 14 insertions(+), 12 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 8cfd645479e1..46e2ba978e20 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -216,11 +216,10 @@ static struct axi_dma_desc *axi_desc_alloc(u32 num) static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan, dma_addr_t *addr) { - struct dw_axi_dma *dw = chan->chip->dw; struct axi_dma_lli *lli; dma_addr_t phys; - lli = dma_pool_zalloc(dw->desc_pool, GFP_NOWAIT, &phys); + lli = dma_pool_zalloc(chan->desc_pool, GFP_NOWAIT, &phys); if (unlikely(!lli)) { dev_err(chan2dev(chan), "%s: not enough descriptors available\n", axi_chan_name(chan)); @@ -236,14 +235,13 @@ static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan, static void axi_desc_put(struct axi_dma_desc *desc) { struct axi_dma_chan *chan = desc->chan; - struct dw_axi_dma *dw = chan->chip->dw; int count = atomic_read(&chan->descs_allocated); struct axi_dma_hw_desc *hw_desc; int descs_put; for (descs_put = 0; descs_put < count; descs_put++) { hw_desc = &desc->hw_desc[descs_put]; - dma_pool_free(dw->desc_pool, hw_desc->lli, hw_desc->llp); + dma_pool_free(chan->desc_pool, hw_desc->lli, hw_desc->llp); } kfree(desc->hw_desc); @@ -360,6 +358,15 @@ static int dma_chan_alloc_chan_resources(struct dma_chan *dchan) return -EBUSY; } + /* LLI address must be aligned to a 64-byte boundary */ + chan->desc_pool = dma_pool_create(dev_name(chan2dev(chan)), + chan->chip->dev, + sizeof(struct axi_dma_lli), + 64, 0); + if (!chan->desc_pool) { + dev_err(chan2dev(chan), "No memory for descriptors\n"); + return -ENOMEM; + } dev_vdbg(dchan2dev(dchan), "%s: allocating\n", axi_chan_name(chan)); pm_runtime_get(chan->chip->dev); @@ -381,6 +388,8 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan) vchan_free_chan_resources(&chan->vc); + dma_pool_destroy(chan->desc_pool); + chan->desc_pool = NULL; dev_vdbg(dchan2dev(dchan), "%s: free resources, descriptor still allocated: %u\n", axi_chan_name(chan), atomic_read(&chan->descs_allocated)); @@ -896,13 +905,6 @@ static int dw_probe(struct platform_device *pdev) if (ret) return ret; - /* Lli address must be aligned to a 64-byte boundary */ - dw->desc_pool = dmam_pool_create(KBUILD_MODNAME, chip->dev, -sizeof(struct axi_dma_lli), 64, 0); - if (!dw->desc_pool) { - dev_err(chip->dev, "No memory for descriptors dma pool\n"); - return -ENOMEM; - } INIT_LIST_HEAD(&dw->dma.channels); for (i = 0; i < hdata->nr_channels; i++) { diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index 41e775e6e593..f886b2bb75de 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -39,6 +39,7 @@ struct axi_dma_chan { u8 id; atomic_tdescs_allocated; + struct dma_pool *desc_pool; struct virt_dma_chanvc; struct axi_dma_desc *desc; @@ -49,7 +50,6 @@ struct axi_dma_chan { struct dw_axi_dma { struct dma_device dma; struct dw_axi_dma_hcfg *hdata; - struct dma_pool *desc_pool; /* channels */ struct axi_dma_chan *chan; -- 2.18.0
[PATCH v2 00/15] dmaengine: dw-axi-dmac: support Intel KeemBay AxiDMA
The below patch series are to support AxiDMA running on Intel KeemBay SoC. The base driver is dw-axi-dmac. This driver only support DMA memory copy transfers. Code refactoring is needed so that additional features can be supported. The features added in this patch series are: - Replacing Linked List with virtual descriptor management. - Remove unrelated hw desc stuff from dma memory pool. - Manage dma memory pool alloc/destroy based on channel activity. - Support dmaengine device_sync() callback. - Support dmaengine device_config(). - Support dmaengine device_prep_slave_sg(). - Support dmaengine device_prep_dma_cyclic(). - Support of_dma_controller_register(). - Support burst residue granularity. - Support Intel KeemBay AxiDMA registers. - Support Intel KeemBay AxiDMA device handshake. - Support Intel KeemBay AxiDMA BYTE and HALFWORD device operation. - Add constraint to Max segment size. This patch series are tested on Intel KeemBay platform. v2: - Rebased to v5.10-rc1 kernel. - Added support for dmaengine device_config(). - Added support for dmaengine device_prep_slave_sg(). - Added support for dmaengine device_prep_dma_cyclic(). - Added support for of_dma_controller_register(). - Added support for burst residue granularity. - Added support for Intel KeemBay AxiDMA registers. - Added support for Intel KeemBay AxiDMA device handshake. - Added support for Intel KeemBay AxiDMA BYTE and HALFWORD device operation. - Added constraint to Max segment size. v1: - Initial version. Patch on top of dw-axi-dma driver. This version improve the descriptor management by replacing Linked List Item (LLI) with virtual descriptor management, only allocate hardware LLI memories from DMA memory pool, manage DMA memory pool alloc/destroy based on channel activity and to support device_sync callback. Sia Jee Heng (15): dt-bindings: dma: Add YAML schemas for dw-axi-dmac dmaengine: dw-axi-dmac: simplify descriptor management dmaengine: dw-axi-dmac: move dma_pool_create() to alloc_chan_resources() dmaengine: dw-axi-dmac: Add device_synchronize() callback dmaengine: dw-axi-dmac: Add device_config operation dmaengine: dw-axi-dmac: Support device_prep_slave_sg dmaegine: dw-axi-dmac: Support device_prep_dma_cyclic() dmaengine: dw-axi-dmac: Support of_dma_controller_register() dmaengine: dw-axi-dmac: Support burst residue granularity dmaengine: dw-axi-dmac: Add Intel KeemBay AxiDMA support dt-binding: dma: dw-axi-dmac: Add support for Intel KeemBay AxiDMA dmaengine: dw-axi-dmac: Add Intel KeemBay DMA register fields dmaengine: dw-axi-dmac: Add Intel KeemBay AxiDMA handshake dmaengine: dw-axi-dmac: Add Intel KeemBay AxiDMA BYTE and HALFWORD registers dmaengine: dw-axi-dmac: Set constraint to the Max segment size .../bindings/dma/snps,dw-axi-dmac.txt | 39 - .../bindings/dma/snps,dw-axi-dmac.yaml| 149 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 696 +++--- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 33 +- 4 files changed, 783 insertions(+), 134 deletions(-) delete mode 100644 Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt create mode 100644 Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml base-commit: 4525c8781ec0701ce824e8bd379ae1b129e26568 -- 2.18.0
[PATCH v2 09/15] dmaengine: dw-axi-dmac: Support burst residue granularity
Add support for DMA_RESIDUE_GRANULARITY_BURST so that AxiDMA can report DMA residue. Existing AxiDMA driver only support data transfer between memory to memory operation, therefore reporting DMA residue to the DMA clients is not supported. Reporting DMA residue to the DMA clients is important as DMA clients shall invoke dmaengine_tx_status() to understand the number of bytes been transferred so that the buffer pointer can be updated accordingly. Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c| 44 --- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 + 2 files changed, 39 insertions(+), 7 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 011cf7134f25..cd99557a716c 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -265,14 +265,36 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, struct dma_tx_state *txstate) { struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); - enum dma_status ret; + struct virt_dma_desc *vdesc; + enum dma_status status; + u32 completed_length; + unsigned long flags; + u32 completed_blocks; + size_t bytes = 0; + u32 length; + u32 len; - ret = dma_cookie_status(dchan, cookie, txstate); + status = dma_cookie_status(dchan, cookie, txstate); + if (status == DMA_COMPLETE) + return status; - if (chan->is_paused && ret == DMA_IN_PROGRESS) - ret = DMA_PAUSED; + spin_lock_irqsave(&chan->vc.lock, flags); - return ret; + vdesc = vchan_find_desc(&chan->vc, cookie); + if (vdesc) { + length = vd_to_axi_desc(vdesc)->length; + completed_blocks = vd_to_axi_desc(vdesc)->completed_blocks; + len = vd_to_axi_desc(vdesc)->hw_desc[0].len; + completed_length = completed_blocks * len; + bytes = length - completed_length; + } else { + bytes = vd_to_axi_desc(vdesc)->length; + } + + spin_unlock_irqrestore(&chan->vc.lock, flags); + dma_set_residue(txstate, bytes); + + return status; } static void write_desc_llp(struct axi_dma_hw_desc *desc, dma_addr_t adr) @@ -497,6 +519,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, desc->chan = chan; num = 0; + desc->length = 0; while (len) { xfer_len = len; @@ -549,7 +572,8 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, set_desc_src_master(hw_desc); set_desc_dest_master(hw_desc, desc); - + hw_desc->len = xfer_len; + desc->length += hw_desc->len; /* update the length and addresses for the next loop cycle */ len -= xfer_len; dst_adr += xfer_len; @@ -612,6 +636,7 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr, chan->direction = direction; desc->chan = chan; chan->cyclic = true; + desc->length = 0; switch (direction) { case DMA_MEM_TO_DEV: @@ -677,6 +702,8 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr, set_desc_src_master(hw_desc); + hw_desc->len = period_len; + desc->length += hw_desc->len; /* * Set end-of-link to the linked descriptor, so that cyclic * callback function can be triggered during interrupt. @@ -757,6 +784,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, } desc->chan = chan; + desc->length = 0; for_each_sg(sgl, sg, sg_len, i) { mem = sg_dma_address(sg); @@ -806,6 +834,8 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, hw_desc->lli->ctl_lo = cpu_to_le32(ctllo); set_desc_src_master(hw_desc); + hw_desc->len = len; + desc->length += hw_desc->len; } if (unlikely(!desc)) @@ -1269,7 +1299,7 @@ static int dw_probe(struct platform_device *pdev) dw->dma.dst_addr_widths = AXI_DMA_BUSWIDTHS; dw->dma.directions = BIT(DMA_MEM_TO_MEM); dw->dma.directions |= BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); - dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; + dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; dw->dma.dev = chip->dev; dw->dma.device_tx_status = dma_chan_tx_status; diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index 651874e5c88f..bdb66d775125 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac
[PATCH v2 04/15] dmaengine: dw-axi-dmac: Add device_synchronize() callback
Add support for device_synchronize() callback function to sync with dmaengine_terminate_sync(). Reviewed-by: Andy Shevchenko Signed-off-by: Sia Jee Heng --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 8 1 file changed, 8 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 46e2ba978e20..56b213211341 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -347,6 +347,13 @@ static void dma_chan_issue_pending(struct dma_chan *dchan) spin_unlock_irqrestore(&chan->vc.lock, flags); } +static void dw_axi_dma_synchronize(struct dma_chan *dchan) +{ + struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); + + vchan_synchronize(&chan->vc); +} + static int dma_chan_alloc_chan_resources(struct dma_chan *dchan) { struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); @@ -940,6 +947,7 @@ static int dw_probe(struct platform_device *pdev) dw->dma.device_free_chan_resources = dma_chan_free_chan_resources; dw->dma.device_prep_dma_memcpy = dma_chan_prep_dma_memcpy; + dw->dma.device_synchronize = dw_axi_dma_synchronize; platform_set_drvdata(pdev, chip); -- 2.18.0
[PATCH v2 01/15] dt-bindings: dma: Add YAML schemas for dw-axi-dmac
YAML schemas Device Tree (DT) binding is the new format for DT to replace the old format. Introduce YAML schemas DT binding for dw-axi-dmac and remove the old version. Signed-off-by: Sia Jee Heng --- .../bindings/dma/snps,dw-axi-dmac.txt | 39 -- .../bindings/dma/snps,dw-axi-dmac.yaml| 124 ++ 2 files changed, 124 insertions(+), 39 deletions(-) delete mode 100644 Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt create mode 100644 Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt deleted file mode 100644 index dbe160400adc.. --- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt +++ /dev/null @@ -1,39 +0,0 @@ -Synopsys DesignWare AXI DMA Controller - -Required properties: -- compatible: "snps,axi-dma-1.01a" -- reg: Address range of the DMAC registers. This should include - all of the per-channel registers. -- interrupt: Should contain the DMAC interrupt number. -- dma-channels: Number of channels supported by hardware. -- snps,dma-masters: Number of AXI masters supported by the hardware. -- snps,data-width: Maximum AXI data width supported by hardware. - (0 - 8bits, 1 - 16bits, 2 - 32bits, ..., 6 - 512bits) -- snps,priority: Priority of channel. Array size is equal to the number of - dma-channels. Priority value must be programmed within [0:dma-channels-1] - range. (0 - minimum priority) -- snps,block-size: Maximum block size supported by the controller channel. - Array size is equal to the number of dma-channels. - -Optional properties: -- snps,axi-max-burst-len: Restrict master AXI burst length by value specified - in this property. If this property is missing the maximum AXI burst length - supported by DMAC is used. [1:256] - -Example: - -dmac: dma-controller@8 { - compatible = "snps,axi-dma-1.01a"; - reg = <0x8 0x400>; - clocks = <&core_clk>, <&cfgr_clk>; - clock-names = "core-clk", "cfgr-clk"; - interrupt-parent = <&intc>; - interrupts = <27>; - - dma-channels = <4>; - snps,dma-masters = <2>; - snps,data-width = <3>; - snps,block-size = <4096 4096 4096 4096>; - snps,priority = <0 1 2 3>; - snps,axi-max-burst-len = <16>; -}; diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml new file mode 100644 index ..e688d25864bc --- /dev/null +++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/snps,dw-axi-dmac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare AXI DMA Controller + +maintainers: + - Eugeniy Paltsev + #include + /* example with snps,dw-axi-dmac */ + dmac: dma-controller@8 { + compatible = "snps,axi-dma-1.01a"; + reg = <0x8 0x400>; + clocks = <&core_clk>, <&cfgr_clk>; + clock-names = "core-clk", "cfgr-clk"; + interrupt-parent = <&intc>; + interrupts = <27>; + #dma-cells = <1>; + dma-channels = <4>; + snps,dma-masters = <2>; + snps,data-width = <3>; + snps,block-size = <4096 4096 4096 4096>; + snps,priority = <0 1 2 3>; + snps,axi-max-burst-len = <16>; + }; -- 2.18.0
Re: [PATCH] matroxfb: avoid -Warray-bounds warning
Hi Am 26.10.20 um 20:39 schrieb Arnd Bergmann: > From: Arnd Bergmann > > The open-coded list_for_each_entry() causes a harmless warning: > > drivers/video/fbdev/matrox/matroxfb_base.c: In function > 'matroxfb_register_driver': > include/linux/kernel.h:856:3: warning: array subscript -98 is outside array > bounds of 'struct list_head[1]' [-Warray-bounds] > > Use the normal list_for_each_entry instead. > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Signed-off-by: Arnd Bergmann Acked-by: Thomas Zimmermann I'll add the patch to drm-misc-next. Thanks! Best regards Thomas > --- > drivers/video/fbdev/matrox/matroxfb_base.c | 8 ++-- > 1 file changed, 2 insertions(+), 6 deletions(-) > > diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c > b/drivers/video/fbdev/matrox/matroxfb_base.c > index 570439b32655..a3853421b263 100644 > --- a/drivers/video/fbdev/matrox/matroxfb_base.c > +++ b/drivers/video/fbdev/matrox/matroxfb_base.c > @@ -1970,9 +1970,7 @@ int matroxfb_register_driver(struct matroxfb_driver* > drv) { > struct matrox_fb_info* minfo; > > list_add(&drv->node, &matroxfb_driver_list); > - for (minfo = matroxfb_l(matroxfb_list.next); > - minfo != matroxfb_l(&matroxfb_list); > - minfo = matroxfb_l(minfo->next_fb.next)) { > + list_for_each_entry(minfo, &matroxfb_list, next_fb) { > void* p; > > if (minfo->drivers_count == MATROXFB_MAX_FB_DRIVERS) > @@ -1990,9 +1988,7 @@ void matroxfb_unregister_driver(struct matroxfb_driver* > drv) { > struct matrox_fb_info* minfo; > > list_del(&drv->node); > - for (minfo = matroxfb_l(matroxfb_list.next); > - minfo != matroxfb_l(&matroxfb_list); > - minfo = matroxfb_l(minfo->next_fb.next)) { > + list_for_each_entry(minfo, &matroxfb_list, next_fb) { > int i; > > for (i = 0; i < minfo->drivers_count; ) { > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
Re: [PATCH 1/4] crypto: add eboiv as a crypto API template
On Mon, Oct 26, 2020 at 8:26 PM Eric Biggers wrote: > > Here's the version of eboiv_create() I recommend (untested): > > static int eboiv_create(struct crypto_template *tmpl, struct rtattr **tb) > { > struct skcipher_instance *inst; > struct eboiv_instance_ctx *ictx; > struct skcipher_alg *alg; > u32 mask; > int err; ... Thank you very much for the review and assistance. I will send out a revised version. Thanks, Gilad -- Gilad Ben-Yossef Chief Coffee Drinker values of β will give rise to dom!
Re: [PATCH v11 01/14] s390/vfio-ap: No need to disable IRQ after queue reset
On Thu, 22 Oct 2020 13:11:56 -0400 Tony Krowiak wrote: > The queues assigned to a matrix mediated device are currently reset when: > > * The VFIO_DEVICE_RESET ioctl is invoked > * The mdev fd is closed by userspace (QEMU) > * The mdev is removed from sysfs. What about the situation when vfio_ap_mdev_group_notifier() is called to tell us that our pointer to KVM is about to become invalid? Do we need to clean up the IRQ stuff there? > > Immediately after the reset of a queue, a call is made to disable > interrupts for the queue. This is entirely unnecessary because the reset of > a queue disables interrupts, so this will be removed. Makes sense. > > Since interrupt processing may have been enabled by the guest, it may also > be necessary to clean up the resources used for interrupt processing. Part > of the cleanup operation requires a reference to KVM, so a check is also > being added to ensure the reference to KVM exists. The reason is because > the release callback - invoked when userspace closes the mdev fd - removes > the reference to KVM. When the remove callback - called when the mdev is > removed from sysfs - is subsequently invoked, there will be no reference to > KVM when the cleanup is performed. Please see below in the code. > > This patch will also do a bit of refactoring due to the fact that the > remove callback, implemented in vfio_ap_drv.c, disables the queue after > resetting it. Instead of the remove callback making a call into the > vfio_ap_ops.c to clean up the resources used for interrupt processing, > let's move the probe and remove callbacks into the vfio_ap_ops.c > file keep all code related to managing queues in a single file. > It would have been helpful to split out the refactoring as a separate patch. This way it is harder to review the code that got moved, because it is intermingled with the changes that intend to change behavior. > Signed-off-by: Tony Krowiak > --- > drivers/s390/crypto/vfio_ap_drv.c | 45 +-- > drivers/s390/crypto/vfio_ap_ops.c | 63 +++ > drivers/s390/crypto/vfio_ap_private.h | 7 +-- > 3 files changed, 52 insertions(+), 63 deletions(-) > > diff --git a/drivers/s390/crypto/vfio_ap_drv.c > b/drivers/s390/crypto/vfio_ap_drv.c > index be2520cc010b..73bd073fd5d3 100644 > --- a/drivers/s390/crypto/vfio_ap_drv.c > +++ b/drivers/s390/crypto/vfio_ap_drv.c > @@ -43,47 +43,6 @@ static struct ap_device_id ap_queue_ids[] = { > > MODULE_DEVICE_TABLE(vfio_ap, ap_queue_ids); > > -/** > - * vfio_ap_queue_dev_probe: > - * > - * Allocate a vfio_ap_queue structure and associate it > - * with the device as driver_data. > - */ > -static int vfio_ap_queue_dev_probe(struct ap_device *apdev) > -{ > - struct vfio_ap_queue *q; > - > - q = kzalloc(sizeof(*q), GFP_KERNEL); > - if (!q) > - return -ENOMEM; > - dev_set_drvdata(&apdev->device, q); > - q->apqn = to_ap_queue(&apdev->device)->qid; > - q->saved_isc = VFIO_AP_ISC_INVALID; > - return 0; > -} > - > -/** > - * vfio_ap_queue_dev_remove: > - * > - * Takes the matrix lock to avoid actions on this device while removing > - * Free the associated vfio_ap_queue structure > - */ > -static void vfio_ap_queue_dev_remove(struct ap_device *apdev) > -{ > - struct vfio_ap_queue *q; > - int apid, apqi; > - > - mutex_lock(&matrix_dev->lock); > - q = dev_get_drvdata(&apdev->device); > - dev_set_drvdata(&apdev->device, NULL); > - apid = AP_QID_CARD(q->apqn); > - apqi = AP_QID_QUEUE(q->apqn); > - vfio_ap_mdev_reset_queue(apid, apqi, 1); > - vfio_ap_irq_disable(q); > - kfree(q); > - mutex_unlock(&matrix_dev->lock); > -} > - > static void vfio_ap_matrix_dev_release(struct device *dev) > { > struct ap_matrix_dev *matrix_dev = dev_get_drvdata(dev); > @@ -186,8 +145,8 @@ static int __init vfio_ap_init(void) > return ret; > > memset(&vfio_ap_drv, 0, sizeof(vfio_ap_drv)); > - vfio_ap_drv.probe = vfio_ap_queue_dev_probe; > - vfio_ap_drv.remove = vfio_ap_queue_dev_remove; > + vfio_ap_drv.probe = vfio_ap_mdev_probe_queue; > + vfio_ap_drv.remove = vfio_ap_mdev_remove_queue; > vfio_ap_drv.ids = ap_queue_ids; > > ret = ap_driver_register(&vfio_ap_drv, THIS_MODULE, VFIO_AP_DRV_NAME); > diff --git a/drivers/s390/crypto/vfio_ap_ops.c > b/drivers/s390/crypto/vfio_ap_ops.c > index e0bde8518745..c471832f0a30 100644 > --- a/drivers/s390/crypto/vfio_ap_ops.c > +++ b/drivers/s390/crypto/vfio_ap_ops.c > @@ -119,7 +119,8 @@ static void vfio_ap_wait_for_irqclear(int apqn) > */ > static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q) > { > - if (q->saved_isc != VFIO_AP_ISC_INVALID && q->matrix_mdev) > + if (q->saved_isc != VFIO_AP_ISC_INVALID && q->matrix_mdev && > + q->matrix_mdev->kvm) Here is the check that the kvm reference exists, you mentioned in the cover letter. You make only the gisc_unregister depend on it, because that's
Re: [PATCH linux-5.9 1/1] net: netfilter: fix KASAN: slab-out-of-bounds Read in nft_flow_rule_create
On Tue, Oct 27, 2020 at 07:42:26AM +0100, Florian Westphal wrote: > Greg KH wrote: > > [ Trimming CC ] > > > On Sun, Oct 25, 2020 at 04:31:57PM -0700, Saeed Mirzamohammadi wrote: > > > Adding stable. > > > > What did that do? > > Its a request to pick up > > commit 31cc578ae2de19c748af06d859019dced68e325d > Author: Saeed Mirzamohammadi > Date: Tue Oct 20 13:41:36 2020 +0200 > > netfilter: nftables_offload: KASAN slab-out-of-bounds Read in > nft_flow_rule_create > > Which lacks a Fixes tag. Should have been: > > Fixes: c9626a2cbdb20e2 ("netfilter: nf_tables: add hardware offload support") > (v5.3+) > > Hope that makes things clearer. That makes it much more obvious and clearer, thank you. Saeed, please be more explicit in the future. thanks, greg k-h
problems with splice from /proc (was Linux 5.10-rc1)
On Sun, Oct 25, 2020 at 03:40:27PM -0700, Linus Torvalds wrote: > The most interesting - to me - change here is Christoph's setf_fs() > removal (it got merged through Al Viro, as you can see in my mergelog > below). It's not a _huge_ change, but it's interesting because the > whole model of set_fs() to specify whether a userspace copy actually > goes to user space or kernel space goes back to pretty much the > original release of Linux, and while the name is entirely historic (it > hasn't used the %fs segment register in a long time), the concept has > remained. Until now. I told Al this yesterday, but figured I would mention it here for others to see. Commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") from this patch series, is breaking the bionic test suite that does the following to verify that splice is working: int in = open("/proc/cpuinfo", O_RDONLY); ASSERT_NE(in, -1); TemporaryFile tf; ssize_t bytes_read = splice(in, nullptr, pipe_fds[1], nullptr, 8*1024, SPLICE_F_MORE | SPLICE_F_MOVE); ASSERT_NE(bytes_read, -1); Before this change, all works well but now splice fails on /proc files (and I'm guessing other virtual filesystems). I'll ask the bionic developers if they can change their test to some other file, but this is a regression and might show up in other "test platforms" as well. Using /proc for this is just so simple because these files are "always there" and don't require any housekeeping for test suites to worry about . thanks, greg k-h
drivers/ptp/ptp_ines.c:837:34: warning: unused variable 'ines_ptp_ctrl_of_match'
Hi Richard, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 4525c8781ec0701ce824e8bd379ae1b129e26568 commit: bad1eaa6ac312ffd7aa46dd5a4d9843b824aa023 ptp: Add a driver for InES time stamping IP core. date: 10 months ago config: x86_64-randconfig-a014-20201027 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project f2c25c70791de95d2466e09b5b58fc37f6ccd7a4) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bad1eaa6ac312ffd7aa46dd5a4d9843b824aa023 git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git git fetch --no-tags linus master git checkout bad1eaa6ac312ffd7aa46dd5a4d9843b824aa023 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/ptp/ptp_ines.c:481:37: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] tag_to_msgtype(ts->tag & 0x7), *msgtype & 0xf); ^~ include/linux/device.h:1792:47: note: expanded from macro 'dev_dbg' dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ~~~ ^~~ drivers/ptp/ptp_ines.c:491:19: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat] ts->portnum, ntohs(*portn)); ^ include/linux/device.h:1792:47: note: expanded from macro 'dev_dbg' dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ~~~ ^~~ include/linux/byteorder/generic.h:142:18: note: expanded from macro 'ntohs' #define ntohs(x) ___ntohs(x) ^~~ include/linux/byteorder/generic.h:137:21: note: expanded from macro '___ntohs' #define ___ntohs(x) __be16_to_cpu(x) ^~~~ include/uapi/linux/byteorder/little_endian.h:42:26: note: expanded from macro '__be16_to_cpu' #define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x)) ^~~~ include/uapi/linux/swab.h:104:2: note: expanded from macro '__swab16' (__builtin_constant_p((__u16)(x)) ? \ ^ drivers/ptp/ptp_ines.c:496:17: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat] ts->seqid, ntohs(*seqid)); ^ include/linux/device.h:1792:47: note: expanded from macro 'dev_dbg' dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ~~~ ^~~ include/linux/byteorder/generic.h:142:18: note: expanded from macro 'ntohs' #define ntohs(x) ___ntohs(x) ^~~ include/linux/byteorder/generic.h:137:21: note: expanded from macro '___ntohs' #define ___ntohs(x) __be16_to_cpu(x) ^~~~ include/uapi/linux/byteorder/little_endian.h:42:26: note: expanded from macro '__be16_to_cpu' #define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x)) ^~~~ include/uapi/linux/swab.h:104:2: note: expanded from macro '__swab16' (__builtin_constant_p((__u16)(x)) ? \ ^ >> drivers/ptp/ptp_ines.c:837:34: warning: unused variable >> 'ines_ptp_ctrl_of_match' [-Wunused-const-variable] static const struct of_device_id ines_ptp_ctrl_of_match[] = { ^ 4 warnings generated. vim +/ines_ptp_ctrl_of_match +837 drivers/ptp/ptp_ines.c 836 > 837 static const struct of_device_id ines_ptp_ctrl_of_match[] = { 838 { .compatible = "ines,ptp-ctrl" }, 839 { } 840 }; 841 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
[RFC -V4 4/6] autonuma, memory tiering: Rate limit NUMA migration throughput
In AutoNUMA memory tiering mode, the hot slow memory pages could be promoted to the fast memory node via AutoNUMA. But this incurs some overhead too. So that sometimes the workload performance may be hurt. To avoid too much disturbing to the workload in these situations, we should make it possible to rate limit the promotion throughput. So, in this patch, we implement a simple rate limit algorithm as follows. The number of the candidate pages to be promoted to the fast memory node via AutoNUMA is counted, if the count exceeds the limit specified by the users, the AutoNUMA promotion will be stopped until the next second. Test the patch with the pmbench memory accessing benchmark with 80:20 read/write ratio and normal access address distribution on a 2 socket Intel server with Optane DC Persistent Memory Model. In the test, the page promotion throughput decreases 50.0% (from 211.7 MB/s to 105.9 MB/s) with the patch, while the benchmark score decreases only 3.3%. A new sysctl knob kernel.numa_balancing_rate_limit_mbps is added for the users to specify the limit. TODO: Add ABI document for new sysctl knob. Signed-off-by: "Huang, Ying" Cc: Andrew Morton Cc: Michal Hocko Cc: Rik van Riel Cc: Mel Gorman Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Dave Hansen Cc: Dan Williams Cc: linux-kernel@vger.kernel.org Cc: linux...@kvack.org --- include/linux/mmzone.h | 7 +++ include/linux/sched/sysctl.h | 6 ++ kernel/sched/fair.c | 29 +++-- kernel/sysctl.c | 8 mm/vmstat.c | 3 +++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 8379432f4f2f..a4fbd711d5e9 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -206,6 +206,9 @@ enum node_stat_item { NR_KERNEL_STACK_KB, /* measured in KiB */ #if IS_ENABLED(CONFIG_SHADOW_CALL_STACK) NR_KERNEL_SCS_KB, /* measured in KiB */ +#endif +#ifdef CONFIG_NUMA_BALANCING + PGPROMOTE_CANDIDATE,/* candidate pages to promote */ #endif NR_VM_NODE_STAT_ITEMS }; @@ -771,6 +774,10 @@ typedef struct pglist_data { struct deferred_split deferred_split_queue; #endif +#ifdef CONFIG_NUMA_BALANCING + unsigned long numa_ts; + unsigned long numa_nr_candidate; +#endif /* Fields commonly accessed by the page reclaim scanner */ /* diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 574d25d6f051..c0cae68e5da0 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -50,6 +50,12 @@ extern unsigned int sysctl_numa_balancing_scan_period_max; extern unsigned int sysctl_numa_balancing_scan_size; extern unsigned int sysctl_numa_balancing_hot_threshold; +#ifdef CONFIG_NUMA_BALANCING +extern unsigned int sysctl_numa_balancing_rate_limit; +#else +#define sysctl_numa_balancing_rate_limit 0 +#endif + #ifdef CONFIG_SCHED_DEBUG extern __read_mostly unsigned int sysctl_sched_migration_cost; extern __read_mostly unsigned int sysctl_sched_nr_migrate; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index fafb312c1b24..e84ae9db7e3c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1076,6 +1076,11 @@ unsigned int sysctl_numa_balancing_scan_delay = 1000; /* The page with hint page fault latency < threshold in ms is considered hot */ unsigned int sysctl_numa_balancing_hot_threshold = 1000; +/* + * Restrict the NUMA migration per second in MB for each target node + * if no enough free space in target node + */ +unsigned int sysctl_numa_balancing_rate_limit = 65536; struct numa_group { refcount_t refcount; @@ -1448,6 +1453,23 @@ static int numa_hint_fault_latency(struct page *page) return (time - last_time) & PAGE_ACCESS_TIME_MASK; } +static bool numa_migration_check_rate_limit(struct pglist_data *pgdat, + unsigned long rate_limit, int nr) +{ + unsigned long nr_candidate; + unsigned long now = jiffies, last_ts; + + mod_node_page_state(pgdat, PGPROMOTE_CANDIDATE, nr); + nr_candidate = node_page_state(pgdat, PGPROMOTE_CANDIDATE); + last_ts = pgdat->numa_ts; + if (now > last_ts + HZ && + cmpxchg(&pgdat->numa_ts, last_ts, now) == last_ts) + pgdat->numa_nr_candidate = nr_candidate; + if (nr_candidate - pgdat->numa_nr_candidate > rate_limit) + return false; + return true; +} + bool should_numa_migrate_memory(struct task_struct *p, struct page * page, int src_nid, int dst_cpu) { @@ -1462,7 +1484,7 @@ bool should_numa_migrate_memory(struct task_struct *p, struct page * page, if (sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING && !node_is_toptier(src_nid)) { struct pglist_data *pgdat; - unsigned long latency, th; + unsigned lon
[RFC -V4 6/6] autonuma, memory tiering: Add page promotion counter
To distinguish the number of promotion from the original inter-socket NUMA balancing migration. The counter is per-node (target node). This is to identify imbalance among NUMA nodes. Signed-off-by: "Huang, Ying" --- include/linux/mmzone.h | 1 + mm/migrate.c | 10 +- mm/vmstat.c| 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index c10efdc92b17..b384489897b7 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -209,6 +209,7 @@ enum node_stat_item { #endif #ifdef CONFIG_NUMA_BALANCING PGPROMOTE_CANDIDATE,/* candidate pages to promote */ + PGPROMOTE_SUCCESS, /* promote successfully */ #endif NR_VM_NODE_STAT_ITEMS }; diff --git a/mm/migrate.c b/mm/migrate.c index d8d80b111a6a..0f4106b6c4fe 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2161,8 +2161,13 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma, putback_lru_page(page); } isolated = 0; - } else + } else { count_vm_numa_event(NUMA_PAGE_MIGRATE); + if (sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING && + !node_is_toptier(page_to_nid(page)) && node_is_toptier(node)) + mod_node_page_state(NODE_DATA(node), PGPROMOTE_SUCCESS, + nr_succeeded); + } BUG_ON(!list_empty(&migratepages)); return isolated; @@ -2287,6 +2292,9 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + page_lru, -HPAGE_PMD_NR); + if (!node_is_toptier(page_to_nid(page)) && node_is_toptier(node)) + mod_node_page_state(NODE_DATA(node), PGPROMOTE_SUCCESS, + HPAGE_PMD_NR); return isolated; out_fail: diff --git a/mm/vmstat.c b/mm/vmstat.c index 2e60cc0232ef..ba5f6f987711 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1217,6 +1217,7 @@ const char * const vmstat_text[] = { #endif #ifdef CONFIG_NUMA_BALANCING "pgpromote_candidate", + "pgpromote_success", #endif /* enum writeback_stat_item counters */ -- 2.28.0
[RFC -V4 1/6] autonuma: Optimize page placement for memory tiering system
With the advent of various new memory types, some machines will have multiple types of memory, e.g. DRAM and PMEM (persistent memory). The memory subsystem of these machines can be called memory tiering system, because the performance of the different types of memory are usually different. In such system, because of the memory accessing pattern changing etc, some pages in the slow memory may become hot globally. So in this patch, the AutoNUMA mechanism is enhanced to optimize the page placement among the different memory types according to hot/cold dynamically. In a typical memory tiering system, there are CPUs, fast memory and slow memory in each physical NUMA node. The CPUs and the fast memory will be put in one logical node (called fast memory node), while the slow memory will be put in another (faked) logical node (called slow memory node). That is, the fast memory is regarded as local while the slow memory is regarded as remote. So it's possible for the recently accessed pages in the slow memory node to be promoted to the fast memory node via the existing AutoNUMA mechanism. The original AutoNUMA mechanism will stop to migrate pages if the free memory of the target node will become below the high watermark. This is a reasonable policy if there's only one memory type. But this makes the original AutoNUMA mechanism almost not work to optimize page placement among different memory types. Details are as follows. It's the common cases that the working-set size of the workload is larger than the size of the fast memory nodes. Otherwise, it's unnecessary to use the slow memory at all. So in the common cases, there are almost always no enough free pages in the fast memory nodes, so that the globally hot pages in the slow memory node cannot be promoted to the fast memory node. To solve the issue, we have 2 choices as follows, a. Ignore the free pages watermark checking when promoting hot pages from the slow memory node to the fast memory node. This will create some memory pressure in the fast memory node, thus trigger the memory reclaiming. So that, the cold pages in the fast memory node will be demoted to the slow memory node. b. Make kswapd of the fast memory node to reclaim pages until the free pages are a little more (about 10MB) than the high watermark. Then, if the free pages of the fast memory node reaches high watermark, and some hot pages need to be promoted, kswapd of the fast memory node will be waken up to demote some cold pages in the fast memory node to the slow memory node. This will free some extra space in the fast memory node, so the hot pages in the slow memory node can be promoted to the fast memory node. The choice "a" will create the memory pressure in the fast memory node. If the memory pressure of the workload is high, the memory pressure may become so high that the memory allocation latency of the workload is influenced, e.g. the direct reclaiming may be triggered. The choice "b" works much better at this aspect. If the memory pressure of the workload is high, the hot pages promotion will stop earlier because its allocation watermark is higher than that of the normal memory allocation. So in this patch, choice "b" is implemented. In addition to the original page placement optimization among sockets, the AutoNUMA mechanism is extended to be used to optimize page placement according to hot/cold among different memory types. So the sysctl user space interface (numa_balancing) is extended in a backward compatible way as follow, so that the users can enable/disable these functionality individually. The sysctl is converted from a Boolean value to a bits field. The definition of the flags is, - 0x0: NUMA_BALANCING_DISABLED - 0x1: NUMA_BALANCING_NORMAL - 0x2: NUMA_BALANCING_MEMORY_TIERING TODO: - Update ABI document: Documentation/sysctl/kernel.txt Signed-off-by: "Huang, Ying" Cc: Andrew Morton Cc: Michal Hocko Cc: Rik van Riel Cc: Mel Gorman Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Dave Hansen Cc: Dan Williams Cc: linux-kernel@vger.kernel.org Cc: linux...@kvack.org --- include/linux/sched/sysctl.h | 5 + kernel/sched/core.c | 9 +++-- kernel/sysctl.c | 7 --- mm/migrate.c | 30 +++--- mm/vmscan.c | 15 +++ 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 3c31ba88aca5..9d85450bc30a 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -39,6 +39,11 @@ enum sched_tunable_scaling { }; extern enum sched_tunable_scaling sysctl_sched_tunable_scaling; +#define NUMA_BALANCING_DISABLED0x0 +#define NUMA_BALANCING_NORMAL 0x1 +#define NUMA_BALANCING_MEMORY_TIERING 0x2 + +extern int sysctl_numa_balancing_mode; extern unsigned int sysctl_numa_balancing_scan_delay; extern unsigned int sysctl_n
[RFC -V4 2/6] autonuma, memory tiering: Skip to scan fast memory
If the AutoNUMA isn't used to optimize the page placement among sockets but only among memory types, the hot pages in the fast memory node couldn't be migrated (promoted) to anywhere. So it's unnecessary to scan the pages in the fast memory node via changing their PTE/PMD mapping to be PROT_NONE. So that the page faults could be avoided too. In the test, if only the memory tiering AutoNUMA mode is enabled, the number of the AutoNUMA hint faults for the DRAM node is reduced to almost 0 with the patch. While the benchmark score doesn't change visibly. Signed-off-by: "Huang, Ying" Suggested-by: Dave Hansen Cc: Andrew Morton Cc: Michal Hocko Cc: Rik van Riel Cc: Mel Gorman Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Dan Williams Cc: linux-kernel@vger.kernel.org Cc: linux...@kvack.org --- include/linux/node.h | 5 + mm/huge_memory.c | 30 +- mm/mprotect.c| 13 - 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/include/linux/node.h b/include/linux/node.h index f7a539390c81..ac0e7a45edff 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -189,4 +189,9 @@ static inline int next_demotion_node(int node) } #endif +static inline bool node_is_toptier(int node) +{ + return node_state(node, N_CPU); +} + #endif /* _LINUX_NODE_H_ */ diff --git a/mm/huge_memory.c b/mm/huge_memory.c index faadc449cca5..a8c2ddd0cc4a 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1795,17 +1796,28 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, } #endif - /* -* Avoid trapping faults against the zero page. The read-only -* data is likely to be read-cached on the local CPU and -* local/remote hits to the zero page are not interesting. -*/ - if (prot_numa && is_huge_zero_pmd(*pmd)) - goto unlock; + if (prot_numa) { + struct page *page; + /* +* Avoid trapping faults against the zero page. The read-only +* data is likely to be read-cached on the local CPU and +* local/remote hits to the zero page are not interesting. +*/ + if (is_huge_zero_pmd(*pmd)) + goto unlock; - if (prot_numa && pmd_protnone(*pmd)) - goto unlock; + if (pmd_protnone(*pmd)) + goto unlock; + page = pmd_page(*pmd); + /* +* Skip scanning top tier node if normal numa +* balancing is disabled +*/ + if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_NORMAL) && + node_is_toptier(page_to_nid(page))) + goto unlock; + } /* * In case prot_numa, we are under mmap_read_lock(mm). It's critical * to not clear pmd intermittently to avoid race with MADV_DONTNEED diff --git a/mm/mprotect.c b/mm/mprotect.c index ce8b8a5eacbb..8abec0c267fa 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, */ if (prot_numa) { struct page *page; + int nid; /* Avoid TLB flush if possible */ if (pte_protnone(oldpte)) @@ -109,7 +111,16 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, * Don't mess with PTEs if page is already on the node * a single-threaded process is running on. */ - if (target_node == page_to_nid(page)) + nid = page_to_nid(page); + if (target_node == nid) + continue; + + /* +* Skip scanning top tier node if normal numa +* balancing is disabled +*/ + if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_NORMAL) && + node_is_toptier(nid)) continue; } -- 2.28.0
[RFC -V4 3/6] autonuma, memory tiering: Hot page selection with hint page fault latency
To optimize page placement in a memory tiering system with AutoNUMA, the hot pages in the slow memory node need to be identified. Essentially, the original AutoNUMA implementation selects the mostly recently accessed (MRU) pages as the hot pages. But this isn't a very good algorithm to identify the hot pages. So, in this patch we implemented a better hot page selection algorithm. Which is based on AutoNUMA page table scanning and hint page fault as follows, - When the page tables of the processes are scanned to change PTE/PMD to be PROT_NONE, the current time is recorded in struct page as scan time. - When the page is accessed, hint page fault will occur. The scan time is gotten from the struct page. And The hint page fault latency is defined as hint page fault time - scan time The shorter the hint page fault latency of a page is, the higher the probability of their access frequency to be higher. So the hint page fault latency is a good estimation of the page hot/cold. But it's hard to find some extra space in struct page to hold the scan time. Fortunately, we can reuse some bits used by the original AutoNUMA. AutoNUMA uses some bits in struct page to store the page accessing CPU and PID (referring to page_cpupid_xchg_last()). Which is used by the multi-stage node selection algorithm to avoid to migrate pages shared accessed by the NUMA nodes back and forth. But for pages in the slow memory node, even if they are shared accessed by multiple NUMA nodes, as long as the pages are hot, they need to be promoted to the fast memory node. So the accessing CPU and PID information are unnecessary for the slow memory pages. We can reuse these bits in struct page to record the scan time for them. For the fast memory pages, these bits are used as before. The remaining problem is how to determine the hot threshold. It's not easy to be done automatically. So we provide a sysctl knob: kernel.numa_balancing_hot_threshold_ms. All pages with hint page fault latency < the threshold will be considered hot. The system administrator can determine the hot threshold via various information, such as PMEM bandwidth limit, the average number of the pages pass the hot threshold, etc. The default hot threshold is 1 second, which works well in our performance test. The patch improves the score of pmbench memory accessing benchmark with 80:20 read/write ratio and normal access address distribution by 11.1% with 40.4% less pages promoted (that is, less overhead) on a 2 socket Intel server with Optance DC Persistent Memory. The downside of the patch is that the response time to the workload hot spot changing may be much longer. For example, - A previous cold memory area becomes hot - The hint page fault will be triggered. But the hint page fault latency isn't shorter than the hot threshold. So the pages will not be promoted. - When the memory area is scanned again, maybe after a scan period, the hint page fault latency measured will be shorter than the hot threshold and the pages will be promoted. To mitigate this, - If there are enough free space in the fast memory node, the hot threshold will not be used, all pages will be promoted upon the hint page fault for fast response. - If fast response is more important for system performance, the administrator can set a higher hot threshold. Signed-off-by: "Huang, Ying" Cc: Andrew Morton Cc: Michal Hocko Cc: Rik van Riel Cc: Mel Gorman Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Dave Hansen Cc: Dan Williams Cc: linux-kernel@vger.kernel.org Cc: linux...@kvack.org --- include/linux/mm.h | 29 include/linux/sched/sysctl.h | 1 + kernel/sched/fair.c | 67 kernel/sysctl.c | 7 mm/huge_memory.c | 13 +-- mm/memory.c | 11 +- mm/migrate.c | 12 +++ mm/mmzone.c | 17 + mm/mprotect.c| 8 - 9 files changed, 160 insertions(+), 5 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index b2f370f0b420..5dde5d08ccdd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1296,6 +1296,18 @@ static inline int page_to_nid(const struct page *page) #endif #ifdef CONFIG_NUMA_BALANCING +/* page access time bits needs to hold at least 4 seconds */ +#define PAGE_ACCESS_TIME_MIN_BITS 12 +#if LAST_CPUPID_SHIFT < PAGE_ACCESS_TIME_MIN_BITS +#definePAGE_ACCESS_TIME_BUCKETS\ + (PAGE_ACCESS_TIME_MIN_BITS - LAST_CPUPID_SHIFT) +#else +#definePAGE_ACCESS_TIME_BUCKETS0 +#endif + +#define PAGE_ACCESS_TIME_MASK \ + (LAST_CPUPID_MASK << PAGE_ACCESS_TIME_BUCKETS) + static inline int cpu_pid_to_cpupid(int cpu, int pid) { return ((cpu & LAST__CPU_MASK) << LAST__PID_SHIFT) | (pid & LAST__PID_MASK); @@ -1338,6 +1350,16 @@ static inline int page_cpup
[RFC -V4 5/6] autonuma, memory tiering: Adjust hot threshold automatically
It isn't easy for the administrator to determine the hot threshold. So in this patch, a method to adjust the hot threshold automatically is implemented. The basic idea is to control the number of the candidate promotion pages to match the promotion rate limit. If the hint page fault latency of a page is less than the hot threshold, we will try to promote the page, and the page is called the candidate promotion page. If the number of the candidate promotion pages in the statistics interval is much more than the promotion rate limit, the hot threshold will be decreased to reduce the number of the candidate promotion pages. Otherwise, the hot threshold will be increased to increase the number of the candidate promotion pages. To make the above method works, in each statistics interval, the total number of the pages to check (on which the hint page faults occur) and the hot/cold distribution need to be stable. Because the page tables are scanned linearly in AutoNUMA, but the hot/cold distribution isn't uniform along the address, the statistics interval should be larger than the AutoNUMA scan period. So in the patch, the max scan period is used as statistics interval and it works well in our tests. The sysctl knob kernel.numa_balancing_hot_threshold_ms becomes the initial value and max value of the hot threshold. The patch improves the score of pmbench memory accessing benchmark with 80:20 read/write ratio and normal access address distribution by 4.4% with 30.8% fewer NUMA page migrations on a 2 socket Intel server with Optance DC Persistent Memory. Because it improves the accuracy of the hot page selection. Signed-off-by: "Huang, Ying" Cc: Andrew Morton Cc: Michal Hocko Cc: Rik van Riel Cc: Mel Gorman Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Dave Hansen Cc: Dan Williams Cc: linux-kernel@vger.kernel.org Cc: linux...@kvack.org --- include/linux/mmzone.h | 3 +++ kernel/sched/fair.c| 40 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index a4fbd711d5e9..c10efdc92b17 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -777,6 +777,9 @@ typedef struct pglist_data { #ifdef CONFIG_NUMA_BALANCING unsigned long numa_ts; unsigned long numa_nr_candidate; + unsigned long numa_threshold_ts; + unsigned long numa_threshold_nr_candidate; + unsigned long numa_threshold; #endif /* Fields commonly accessed by the page reclaim scanner */ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e84ae9db7e3c..227007f2b9d7 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1470,6 +1470,35 @@ static bool numa_migration_check_rate_limit(struct pglist_data *pgdat, return true; } +#define NUMA_MIGRATION_ADJUST_STEPS16 + +static void numa_migration_adjust_threshold(struct pglist_data *pgdat, + unsigned long rate_limit, + unsigned long ref_th) +{ + unsigned long now = jiffies, last_th_ts, th_period; + unsigned long unit_th, th; + unsigned long nr_cand, ref_cand, diff_cand; + + th_period = msecs_to_jiffies(sysctl_numa_balancing_scan_period_max); + last_th_ts = pgdat->numa_threshold_ts; + if (now > last_th_ts + th_period && + cmpxchg(&pgdat->numa_threshold_ts, last_th_ts, now) == last_th_ts) { + ref_cand = rate_limit * + sysctl_numa_balancing_scan_period_max / 1000; + nr_cand = node_page_state(pgdat, PGPROMOTE_CANDIDATE); + diff_cand = nr_cand - pgdat->numa_threshold_nr_candidate; + unit_th = ref_th / NUMA_MIGRATION_ADJUST_STEPS; + th = pgdat->numa_threshold ? : ref_th; + if (diff_cand > ref_cand * 11 / 10) + th = max(th - unit_th, unit_th); + else if (diff_cand < ref_cand * 9 / 10) + th = min(th + unit_th, ref_th); + pgdat->numa_threshold_nr_candidate = nr_cand; + pgdat->numa_threshold = th; + } +} + bool should_numa_migrate_memory(struct task_struct *p, struct page * page, int src_nid, int dst_cpu) { @@ -1484,19 +1513,22 @@ bool should_numa_migrate_memory(struct task_struct *p, struct page * page, if (sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING && !node_is_toptier(src_nid)) { struct pglist_data *pgdat; - unsigned long rate_limit, latency, th; + unsigned long rate_limit, latency, th, def_th; pgdat = NODE_DATA(dst_nid); if (pgdat_free_space_enough(pgdat)) return true; - th = sysctl_numa_balancing_hot_threshold; + def_th = sysctl_numa_balancing_hot_threshold; + rate_limit = +
[RFC -V4 0/6] autonuma: Optimize memory placement for memory tiering system
With the advent of various new memory types, some machines will have multiple types of memory, e.g. DRAM and PMEM (persistent memory). The memory subsystem of these machines can be called memory tiering system, because the performance of the different types of memory are usually different. After commit c221c0b0308f ("device-dax: "Hotplug" persistent memory for use like normal RAM"), the PMEM could be used as the cost-effective volatile memory in separate NUMA nodes. In a typical memory tiering system, there are CPUs, DRAM and PMEM in each physical NUMA node. The CPUs and the DRAM will be put in one logical node, while the PMEM will be put in another (faked) logical node. To optimize the system overall performance, the hot pages should be placed in DRAM node. To do that, we need to identify the hot pages in the PMEM node and migrate them to DRAM node via NUMA migration. In the original AutoNUMA, there are already a set of existing mechanisms to identify the pages recently accessed by the CPUs in a node and migrate the pages to the node. So we can reuse these mechanisms to build the mechanisms to optimize the page placement in the memory tiering system. This has been implemented in this patchset. At the other hand, the cold pages should be placed in PMEM node. So, we also need to identify the cold pages in the DRAM node and migrate them to PMEM node. In the following patchset, [RFC][PATCH 0/9] [v4][RESEND] Migrate Pages in lieu of discard https://lore.kernel.org/linux-mm/20201007161736.acc6e...@viggo.jf.intel.com/ A mechanism to demote the cold DRAM pages to PMEM node under memory pressure is implemented. Based on that, the cold DRAM pages can be demoted to PMEM node proactively to free some memory space on DRAM node. And this frees the space on DRAM node for the hot PMEM pages to be promoted to. This has been implemented in this patchset too. The patchset is based on the following not-yet-merged patchset, [RFC][PATCH 0/9] [v4][RESEND] Migrate Pages in lieu of discard https://lore.kernel.org/linux-mm/20201007161736.acc6e...@viggo.jf.intel.com/ This is part of a larger patch set. If you want to apply these or play with them, I'd suggest using the tree from below, https://github.com/hying-caritas/linux/commits/autonuma-r4 We have tested the solution with the pmbench memory accessing benchmark with the 80:20 read/write ratio and the normal access address distribution on a 2 socket Intel server with Optane DC Persistent Memory Model. The test results of the base kernel and step by step optimizations are as follows, Throughput Promotion DRAM bandwidth access/s MB/sMB/s --- -- -- Base74238178.0 4291.7 Patch 1146050652.3 359.4 11248.6 Patch 2146300787.1 355.2 11237.2 Patch 3162536383.0 211.7 11890.4 Patch 4157187775.0 105.9 10412.3 Patch 5164028415.2 73.3 10810.6 Patch 6162666229.4 74.6 10715.1 The whole patchset improves the benchmark score up to 119.1%. The basic AutoNUMA based optimization solution (patch 1), the hot page selection algorithm (patch 3), and the threshold automatic adjustment algorithms (patch 5) improves the performance or reduce the overhead (promotion MB/s) mostly. Changelog: v4: - Rebased on the latest page demotion patchset. (which bases on v5.9-rc6) - Add page promotion counter. v3: - Move the rate limit control as late as possible per Mel Gorman's comments. - Revise the hot page selection implementation to store page scan time in struct page. - Code cleanup. - Rebased on the latest page demotion patchset. v2: - Addressed comments for V1. - Rebased on v5.5. Huang Ying (6): autonuma: Optimize page placement for memory tiering system autonuma, memory tiering: Skip to scan fast memory autonuma, memory tiering: Hot page selection with hint page fault latency autonuma, memory tiering: Rate limit NUMA migration throughput autonuma, memory tiering: Adjust hot threshold automatically autonuma, memory tiering: Add page promotion counter include/linux/mm.h | 29 include/linux/mmzone.h | 11 include/linux/node.h | 5 ++ include/linux/sched/sysctl.h | 12 kernel/sched/core.c | 9 +-- kernel/sched/fair.c | 124 +++ kernel/sysctl.c | 22 ++- mm/huge_memory.c | 41 mm/memory.c | 11 +++- mm/migrate.c | 52 +-- mm/mmzone.c | 17 + mm/mprotect.c| 19 +- mm/vmscan.c | 15 + mm/vmstat.c | 4 ++ 14 files changed, 345 insertions(+), 26 deletions(-) --
[PATCH v2] documentation: arm: sunxi: add Allwinner H6 documents
Add the current Allwinner H6 datasheet and user manual. Signed-off-by: Wilken Gottwalt --- Changes in v2: - changed email because of serious problems between my old email provider and the lkml --- Documentation/arm/sunxi.rst | 10 ++ 1 file changed, 10 insertions(+) diff --git a/Documentation/arm/sunxi.rst b/Documentation/arm/sunxi.rst index 62b533d0ba94..0c536ae1d7c2 100644 --- a/Documentation/arm/sunxi.rst +++ b/Documentation/arm/sunxi.rst @@ -148,3 +148,13 @@ SunXi family * User Manual http://dl.linux-sunxi.org/A64/Allwinner%20A64%20User%20Manual%20v1.0.pdf + + - Allwinner H6 + + * Datasheet + + https://linux-sunxi.org/images/5/5c/Allwinner_H6_V200_Datasheet_V1.1.pdf + + * User Manual + + https://linux-sunxi.org/images/4/46/Allwinner_H6_V200_User_Manual_V1.1.pdf -- 2.29.0
Re: [PATCH V3 2/4] misc: vop: do not allocate and reassign the used ring
On Mon, Oct 26, 2020 at 03:04:45AM +, Sherry Sun wrote: > Hi Greg & Christoph, > > > Subject: Re: [PATCH V3 2/4] misc: vop: do not allocate and reassign the used > > ring > > > > On Thu, Oct 22, 2020 at 01:06:36PM +0800, Sherry Sun wrote: > > > We don't need to allocate and reassign the used ring here and remove > > > the used_address_updated flag.Since RC has allocated the entire vring, > > > including the used ring. Simply add the corresponding offset can get > > > the used ring address. > > > > Someone needs to verify this vs the existing intel implementations. > > Hi Greg, @gre...@linuxfoundation.org, sorry I don't have the Intel MIC > devices so cannot test it, do you know anyone who can help test this patch > changes on the Intel MIC platform? Thanks. Why not ask the authors/maintainers of that code? greg k-h
[PATCHv5] perf kvm: add kvm-stat for arm64
Add support for perf kvm stat on arm64 platform. Example: # perf kvm stat report Analyze events for all VMs, all VCPUs: VM-EXITSamples Samples% Time%Min TimeMax Time Avg time DABT_LOW 66186798.91%40.45% 2.19us 3364.65us 6.24us ( +- 0.34% ) IRQ 4598 0.69%57.44% 2.89us 3397.59us 1276.27us ( +- 1.61% ) WFx 1475 0.22% 1.71% 2.22us 3388.63us118.31us ( +- 8.69% ) IABT_LOW 1018 0.15% 0.38% 2.22us 2742.07us 38.29us ( +- 12.55% ) SYS64180 0.03% 0.01% 2.07us112.91us 6.57us ( +- 14.95% ) HVC64 17 0.00% 0.01% 2.19us322.35us 42.95us ( +- 58.98% ) Total Samples:669155, Total events handled time:10216387.86us. Signed-off-by: Sergey Senozhatsky Reviewed-by: Leo Yan Tested-by: Leo Yan --- v5: rebased against perf/core (Arnaldo) v4: rebased against perf/core (Leo) v3: report ARM_EXCEPTION_IL exceptions (Leo) v2: reworked the patch after offline discussion with Suleiman tools/perf/arch/arm64/Makefile| 1 + tools/perf/arch/arm64/util/Build | 1 + .../arch/arm64/util/arm64_exception_types.h | 92 +++ tools/perf/arch/arm64/util/kvm-stat.c | 85 + 4 files changed, 179 insertions(+) create mode 100644 tools/perf/arch/arm64/util/arm64_exception_types.h create mode 100644 tools/perf/arch/arm64/util/kvm-stat.c diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile index dbef716a1913..fab3095fb5d0 100644 --- a/tools/perf/arch/arm64/Makefile +++ b/tools/perf/arch/arm64/Makefile @@ -4,6 +4,7 @@ PERF_HAVE_DWARF_REGS := 1 endif PERF_HAVE_JITDUMP := 1 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 +HAVE_KVM_STAT_SUPPORT := 1 # # Syscall table generation for perf diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build index b53294d74b01..8d2b9bcfffca 100644 --- a/tools/perf/arch/arm64/util/Build +++ b/tools/perf/arch/arm64/util/Build @@ -2,6 +2,7 @@ perf-y += header.o perf-y += machine.o perf-y += perf_regs.o perf-y += tsc.o +perf-y += kvm-stat.o perf-$(CONFIG_DWARF) += dwarf-regs.o perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/arm64/util/arm64_exception_types.h b/tools/perf/arch/arm64/util/arm64_exception_types.h new file mode 100644 index ..27c981ebe401 --- /dev/null +++ b/tools/perf/arch/arm64/util/arm64_exception_types.h @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef ARCH_PERF_ARM64_EXCEPTION_TYPES_H +#define ARCH_PERF_ARM64_EXCEPTION_TYPES_H + +/* Per asm/virt.h */ +#define HVC_STUB_ERR 0xbadca11 + +/* Per asm/kvm_asm.h */ +#define ARM_EXCEPTION_IRQ 0 +#define ARM_EXCEPTION_EL1_SERROR 1 +#define ARM_EXCEPTION_TRAP 2 +#define ARM_EXCEPTION_IL 3 +/* The hyp-stub will return this for any kvm_call_hyp() call */ +#define ARM_EXCEPTION_HYP_GONE HVC_STUB_ERR + +#define kvm_arm_exception_type \ + {ARM_EXCEPTION_IRQ, "IRQ" }, \ + {ARM_EXCEPTION_EL1_SERROR, "SERROR"}, \ + {ARM_EXCEPTION_TRAP,"TRAP" }, \ + {ARM_EXCEPTION_IL, "ILLEGAL" }, \ + {ARM_EXCEPTION_HYP_GONE,"HYP_GONE" } + +/* Per asm/esr.h */ +#define ESR_ELx_EC_UNKNOWN (0x00) +#define ESR_ELx_EC_WFx (0x01) +/* Unallocated EC: 0x02 */ +#define ESR_ELx_EC_CP15_32 (0x03) +#define ESR_ELx_EC_CP15_64 (0x04) +#define ESR_ELx_EC_CP14_MR (0x05) +#define ESR_ELx_EC_CP14_LS (0x06) +#define ESR_ELx_EC_FP_ASIMD(0x07) +#define ESR_ELx_EC_CP10_ID (0x08) /* EL2 only */ +#define ESR_ELx_EC_PAC (0x09) /* EL2 and above */ +/* Unallocated EC: 0x0A - 0x0B */ +#define ESR_ELx_EC_CP14_64 (0x0C) +/* Unallocated EC: 0x0d */ +#define ESR_ELx_EC_ILL (0x0E) +/* Unallocated EC: 0x0F - 0x10 */ +#define ESR_ELx_EC_SVC32 (0x11) +#define ESR_ELx_EC_HVC32 (0x12) /* EL2 only */ +#define ESR_ELx_EC_SMC32 (0x13) /* EL2 and above */ +/* Unallocated EC: 0x14 */ +#define ESR_ELx_EC_SVC64 (0x15) +#define ESR_ELx_EC_HVC64 (0x16) /* EL2 and above */ +#define ESR_ELx_EC_SMC64 (0x17) /* EL2 and above */ +#define ESR_ELx_EC_SYS64 (0x18) +#define ESR_ELx_EC_SVE (0x19) +#define ESR_ELx_EC_ERET(0x1a) /* EL2 only */ +/* Unallocated EC: 0x1b - 0x1E */ +#define ESR_ELx_EC_IMP_DEF (0x1f) /* EL3 only */ +#define ESR_ELx_EC_IABT_LOW(0x20) +#define ESR_ELx_EC_IABT_CUR(0x21) +#define ESR_ELx_EC_PC_ALIGN(0x22) +/* Unallocated EC: 0x23 */ +#define ESR_ELx_EC_DABT_LOW(0x24) +#define ESR_ELx_EC_DABT_CUR(0x25) +#define ESR_ELx_EC_SP_ALIGN(0x26) +/* Unallocated EC: 0
Re: [PATCH 1/1] video: fbdev: fix divide error in fbcon_switch
On Mon, Oct 26, 2020 at 10:00:11AM -0700, Saeed Mirzamohammadi wrote: > Thanks, adding stable. Why? What are we supposed to do with this?
Re: [PATCH linux-5.9 1/1] net: netfilter: fix KASAN: slab-out-of-bounds Read in nft_flow_rule_create
On Sun, Oct 25, 2020 at 04:31:57PM -0700, Saeed Mirzamohammadi wrote: > Adding stable. What did that do? confused, greg k-h
Re: [PATCH v3] cpufreq: tegra194: get consistent cpuinfo_cur_freq
Ping. Frequency returned by 'cpuinfo_cur_freq' using counters is not fixed and keeps changing slightly. This change returns a consistent value from freq_table. If the reconstructed frequency has acceptable delta from the last written value, then return the frequency corresponding to the last written ndiv value from freq_table. Otherwise, print a warning and return the reconstructed freq. Signed-off-by: Sumit Gupta --- Sending only this patch as other patch not required after the change to convert 'pr_warn' to 'pr_info' in cpufreq core for unlisted freq. Changelog v1[2] -> v3: - Removed unwanted checks for cpu_online and max cluster number - Used WARN_ON_ONCE to avoid print flooding. v1[1] -> v2: - Minor changes to improve comments and reduce debug prints. - Get freq table from cluster specific data instead of policy. [2] https://marc.info/?l=linux-tegra&m=160216218511280&w=2 [1] https://marc.info/?l=linux-arm-kernel&m=160028821117535&w=2 drivers/cpufreq/tegra194-cpufreq.c | 62 -- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index e1d931c..7901587 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -180,9 +180,61 @@ static unsigned int tegra194_get_speed_common(u32 cpu, u32 delay) return (rate_mhz * KHZ); /* in KHz */ } +static void get_cpu_ndiv(void *ndiv) +{ + u64 ndiv_val; + + asm volatile("mrs %0, s3_0_c15_c0_4" : "=r" (ndiv_val) : ); + + *(u64 *)ndiv = ndiv_val; +} + +static void set_cpu_ndiv(void *data) +{ + struct cpufreq_frequency_table *tbl = data; + u64 ndiv_val = (u64)tbl->driver_data; + + asm volatile("msr s3_0_c15_c0_4, %0" : : "r" (ndiv_val)); +} + static unsigned int tegra194_get_speed(u32 cpu) { - return tegra194_get_speed_common(cpu, US_DELAY); + struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); + struct cpufreq_frequency_table *pos; + unsigned int rate; + u64 ndiv; + int ret; + u32 cl; + + smp_call_function_single(cpu, get_cpu_cluster, &cl, true); + + /* reconstruct actual cpu freq using counters */ + rate = tegra194_get_speed_common(cpu, US_DELAY); + + /* get last written ndiv value */ + ret = smp_call_function_single(cpu, get_cpu_ndiv, &ndiv, true); + if (WARN_ON_ONCE(ret)) + return rate; + + /* +* If the reconstructed frequency has acceptable delta from +* the last written value, then return freq corresponding +* to the last written ndiv value from freq_table. This is +* done to return consistent value. +*/ + cpufreq_for_each_valid_entry(pos, data->tables[cl]) { + if (pos->driver_data != ndiv) + continue; + + if (abs(pos->frequency - rate) > 115200) { + pr_warn("cpufreq: cpu%d,cur:%u,set:%u,set ndiv:%llu\n", + cpu, rate, pos->frequency, ndiv); + } else { + rate = pos->frequency; + } + break; + } + return rate; } static int tegra194_cpufreq_init(struct cpufreq_policy *policy) @@ -209,14 +261,6 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy) return 0; } -static void set_cpu_ndiv(void *data) -{ - struct cpufreq_frequency_table *tbl = data; - u64 ndiv_val = (u64)tbl->driver_data; - - asm volatile("msr s3_0_c15_c0_4, %0" : : "r" (ndiv_val)); -} - static int tegra194_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { -- 2.7.4
Re: For review: seccomp_user_notif(2) manual page
On 10/26/20 4:54 PM, Jann Horn wrote: > On Sun, Oct 25, 2020 at 5:32 PM Michael Kerrisk (man-pages) > wrote: [...] >> I tried applying the patch below to vanilla 5.9.0. >> (There's one typo: s/ENOTCON/ENOTCONN). >> >> It seems not to work though; when I send a signal to my test >> target process that is sleeping waiting for the notification >> response, the process enters the uninterruptible D state. >> Any thoughts? > > Ah, yeah, I think I was completely misusing the wait API. I'll go change that. > > (Btw, in general, for reports about hangs like that, it can be helpful > to have the contents of /proc/$pid/stack. And for cases where CPUs are > spinning, the relevant part from the output of the "L" sysrq, or > something like that.) Thanks for the tipcs! > Also, I guess we can probably break this part of UAPI after all, since > the only user of this interface seems to currently be completely > broken in this case anyway? So I think we want the other > implementation without the ->canceled_reqs logic after all. Okay. > I'm a bit on the fence now on whether non-blocking mode should use > ENOTCONN or not... I guess if we returned ENOENT even when there are > no more listeners, you'd have to disambiguate through the poll() > revents, which would be kinda ugly? I must confess, I'm not quite clear on which two cases you are trying to distinguish. Can you elaborate? > I'll try to turn this into a proper patch submission... Thank you!! Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/
Re: [PATCH] mm/hugetable.c: align some prints
On Mon, Oct 26, 2020 at 05:23:43PM -0700, Mike Kravetz wrote: > On 10/9/20 9:23 AM, Hui Su wrote: > > in old code, it shows like: > > Node 0 ShmemHugePages:0 kB > > Node 0 ShmemPmdMapped:0 kB > > Node 0 FileHugePages:0 kB > > Node 0 FilePmdMapped:0 kB > > Node 0 HugePages_Total: 0 > > Node 0 HugePages_Free: 0 > > Node 0 HugePages_Surp: 0 > > > > which is not align. So we align it. > > > > Signed-off-by: Hui Su > > Apologies for the late reply. > > I assume you you just want to make the output look better. Correct? > > To be honest, I am not sure about the policy for changing the output > of sysfs files. My preference would be to not change the output. Why? > When the output is changed there is always the possibility that someone > may have written code that depends on the current format. It looks like > the output has been misaligned since the day the code was first written. > > This code was recently changed to use sysfs_emit_at() instead of > sprintf(). At that time Greg noted that this also violates the sysfs > rule of one value per file. So, it appears there may be a bigger issue > than alignment. > > Greg, > Is it OK to break up these sysfs files to be one value per file if they > contained multiple values from day 1 of their existence? I would prefer > not to touch them in case some is depending on current format. You should create multiple files, with a different name, and then remove this file. Any tool that uses sysfs should be able to handle a file going away, don't change the format of the data in the file, otherwise there's no way for anyone to know what is happening. thanks, greg k-h
Re: [PATCH v4] Add power/gpu_frequency tracepoint.
On Mon, Oct 26, 2020 at 03:25:22PM -0700, Peiyong Lin wrote: > Hi there, > > May I ask for a review please? Please do not top-post, and you just sent this a few days ago, in the middle of the merge window when we could not do anything. Give maintainers time to catch up, and they will get to it... greg k-h
Re: [PATCH net-next 09/11] ath6kl: fix enum-conversion warning
Arnd Bergmann writes: > From: Arnd Bergmann > > gcc -Wextra points out a type mismatch > > drivers/net/wireless/ath/ath6kl/wmi.c: In function 'ath6kl_wmi_cmd_send': > drivers/net/wireless/ath/ath6kl/wmi.c:1825:19: warning: implicit conversion > from 'enum ' to 'enum wmi_data_hdr_data_type' [-Wenum-conversion] > 1825 |false, false, 0, NULL, if_idx); > | ^ > > As far as I can tell, the numeric value is current here, > so just use the correct enum literal instead of 'false'. > > Fixes: bdcd81707973 ("Add ath6kl cleaned up driver") > Signed-off-by: Arnd Bergmann Looks good to me. I'll take this to my ath.git tree. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [PATCH v4 16/16] xhci: tegra: Enable ELPG for runtime/system PM
Hi JC, I love your patch! Yet something to improve: [auto build test ERROR on tegra/for-next] [also build test ERROR on robh/for-next usb/usb-testing char-misc/char-misc-testing staging/staging-testing driver-core/driver-core-testing v5.10-rc1 next-20201026] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/JC-Kuo/Tegra-XHCI-controller-ELPG-support/20201016-211159 base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next config: arm-defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/656fb4e32b5058dde63d15949b5ad35fbe573d4c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review JC-Kuo/Tegra-XHCI-controller-ELPG-support/20201016-211159 git checkout 656fb4e32b5058dde63d15949b5ad35fbe573d4c # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>, old ones prefixed by <<): >> ERROR: modpost: "xhci_get_rhub" [drivers/usb/host/xhci-tegra.ko] undefined! --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH] usb: typec: Prevent setting invalid opmode value
Hi Heikki, Thanks a lot for the review. On 10/26/2020 6:35 PM, Heikki Krogerus wrote: > On Thu, Oct 22, 2020 at 03:12:14PM +0530, Sriharsha Allenki wrote: >> Setting opmode to invalid values would lead to a >> paging fault failure when there is an access to the >> power_operation_mode. >> >> Prevent this by checking the validity of the value >> that the opmode is being set. >> >> Cc: >> Fixes: fab9288428ec ("usb: USB Type-C connector class") >> Signed-off-by: Sriharsha Allenki >> --- >> drivers/usb/typec/class.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c >> index 35eec70..63efe16 100644 >> --- a/drivers/usb/typec/class.c >> +++ b/drivers/usb/typec/class.c >> @@ -1427,7 +1427,8 @@ void typec_set_pwr_opmode(struct typec_port *port, >> { >> struct device *partner_dev; >> >> -if (port->pwr_opmode == opmode) >> +if ((port->pwr_opmode == opmode) || (opmode < TYPEC_PWR_MODE_USB) || > You don't need to check if opmode < anything. opmode is enum which > apparently means that GCC handles it as unsigned. Since > TYPEC_PWR_MODE_USB is 0 it means opmode < TYPEC_PWR_MODE_USB is never > true. > >> +(opmode > TYPEC_PWR_MODE_PD)) >> return; > You really need to print an error at the very least. Otherwise we will > just silently hide possible driver bugs. > > To be honest, I'm not a big fan of this kind of checks. They have > created more problems than they have fixed in more than one occasion > to me. For example, there really is no guarantee that the maximum will > always be TYPEC_PWR_MODE_PD, which means we probable should have > something like TYPEC_PWR_MODE_MAX defined somewhere that you compare > the opmode value to instead of TYPEC_PWR_MODE_PD to play it safe, but > let's not bother with that for now (it will create other problems). > > Basically, with functions like this, especially since it doesn't > return anything, the responsibility of checking the validity of the > parameters that the caller supplies to it belongs to the caller IMO, > not the function itself. I would be happy to explain that in the > kernel doc style comment of the function. > > If you still feel that this change is really necessary, meaning you > have some actual case where the caller can _not_ check the range > before calling this function, then explain the case you have carefully > in the commit message and add the check as a separate condition: We had a bug that was setting this out of index opmode leading to the mentioned paging fault, and as you have suggested we could have added the range check there and prevented this. But there are many calls to this function, and I thought it would be a good idea to abstract that range check into this function to prevent adding multiple range checks over the driver. And further motivation was also to prevent any potential unknown bugs. I will resend the patch with the suggested changes; separate condition and anerror statement if the above justification is acceptable, else will propose a patch to improve the documentation. Thanks, Sriharsha > > diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c > index 35eec707cb512..7de6913d90f9c 100644 > --- a/drivers/usb/typec/class.c > +++ b/drivers/usb/typec/class.c > @@ -1430,6 +1430,11 @@ void typec_set_pwr_opmode(struct typec_port *port, > if (port->pwr_opmode == opmode) > return; > > + if (opmode > TYPEC_PWR_OPMODE_PD) { > + dev_err(&port->dev, "blah-blah-blah\n"); > + return; > + } > + > port->pwr_opmode = opmode; > sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode"); > kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); > > Otherwise you can just propose a patch that improves the documentation > of this function, explaining that it does not take any responsibility > over the parameters passed to it for now. > > > thanks, > -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Re: kvm+nouveau induced lockdep gripe
On Mon, 2020-10-26 at 20:53 +0100, Sebastian Andrzej Siewior wrote: > > Could you try this, please? Nogo, first call of sched_setscheduler() is via kthread_create(). I confirmed that nuking that (gratuitous user foot saving override) call on top of moving sched_set_fifo() does shut it up, but that won't fly. > --- a/kernel/irq/manage.c > +++ b/kernel/irq/manage.c > @@ -1155,6 +1155,8 @@ static int irq_thread(void *data) > irqreturn_t (*handler_fn)(struct irq_desc *desc, > struct irqaction *action); > > + sched_set_fifo(current); > + > if (force_irqthreads && test_bit(IRQTF_FORCED_THREAD, > &action->thread_flags)) > handler_fn = irq_forced_thread_fn; > @@ -1320,8 +1322,6 @@ setup_irq_thread(struct irqaction *new, > if (IS_ERR(t)) > return PTR_ERR(t); > > - sched_set_fifo(t); > - > /* >* We keep the reference to the task struct even if >* the thread dies to avoid that the interrupt code > [ 150.926954] == [ 150.926967] WARNING: possible circular locking dependency detected [ 150.926981] 5.10.0.g3650b22-master #13 Tainted: G S E [ 150.926993] -- [ 150.927005] libvirtd/1833 is trying to acquire lock: [ 150.927016] 921a45ed55a8 (&mm->mmap_lock#2){}-{3:3}, at: mpol_rebind_mm+0x1e/0x50 [ 150.927052] but task is already holding lock: [ 150.927064] ad585410 (&cpuset_rwsem){}-{0:0}, at: cpuset_attach+0x38/0x390 [ 150.927094] which lock already depends on the new lock. [ 150.927108] the existing dependency chain (in reverse order) is: [ 150.927122] -> #3 (&cpuset_rwsem){}-{0:0}: [ 150.927145]cpuset_read_lock+0x39/0xd0 [ 150.927160]__sched_setscheduler+0x456/0xa90 [ 150.927173]_sched_setscheduler+0x69/0x70 [ 150.927187]__kthread_create_on_node+0x114/0x170 [ 150.927205]kthread_create_on_node+0x37/0x40 [ 150.927223]setup_irq_thread+0x33/0xb0 [ 150.927238]__setup_irq+0x4e0/0x7c0 [ 150.927254]request_threaded_irq+0xf8/0x160 [ 150.927393]nvkm_pci_oneinit+0x4c/0x70 [nouveau] [ 150.927469]nvkm_subdev_init+0x60/0x1e0 [nouveau] [ 150.927603]nvkm_device_init+0x10b/0x240 [nouveau] [ 150.927733]nvkm_udevice_init+0x49/0x70 [nouveau] [ 150.927804]nvkm_object_init+0x3d/0x180 [nouveau] [ 150.927871]nvkm_ioctl_new+0x1a1/0x260 [nouveau] [ 150.927938]nvkm_ioctl+0x10a/0x240 [nouveau] [ 150.928001]nvif_object_ctor+0xeb/0x150 [nouveau] [ 150.928069]nvif_device_ctor+0x1f/0x60 [nouveau] [ 150.928201]nouveau_cli_init+0x1ac/0x590 [nouveau] [ 150.928332]nouveau_drm_device_init+0x68/0x800 [nouveau] [ 150.928462]nouveau_drm_probe+0xfb/0x200 [nouveau] [ 150.928483]local_pci_probe+0x42/0x90 [ 150.928501]pci_device_probe+0xe7/0x1a0 [ 150.928519]really_probe+0xf7/0x4d0 [ 150.928536]driver_probe_device+0x5d/0x140 [ 150.928552]device_driver_attach+0x4f/0x60 [ 150.928569]__driver_attach+0xa4/0x140 [ 150.928584]bus_for_each_dev+0x67/0x90 [ 150.928600]bus_add_driver+0x18c/0x230 [ 150.928616]driver_register+0x5b/0xf0 [ 150.928633]do_one_initcall+0x54/0x2f0 [ 150.928650]do_init_module+0x5b/0x21b [ 150.928667]load_module+0x1e40/0x2370 [ 150.928682]__do_sys_finit_module+0x98/0xe0 [ 150.928698]do_syscall_64+0x33/0x40 [ 150.928716]entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 150.928731] -> #2 (&device->mutex){+.+.}-{3:3}: [ 150.928761]__mutex_lock+0x90/0x9c0 [ 150.928895]nvkm_udevice_fini+0x23/0x70 [nouveau] [ 150.928975]nvkm_object_fini+0xb8/0x210 [nouveau] [ 150.929048]nvkm_object_fini+0x73/0x210 [nouveau] [ 150.929119]nvkm_ioctl_del+0x7e/0xa0 [nouveau] [ 150.929191]nvkm_ioctl+0x10a/0x240 [nouveau] [ 150.929258]nvif_object_dtor+0x4a/0x60 [nouveau] [ 150.929326]nvif_client_dtor+0xe/0x40 [nouveau] [ 150.929455]nouveau_cli_fini+0x7a/0x90 [nouveau] [ 150.929586]nouveau_drm_postclose+0xaa/0xe0 [nouveau] [ 150.929638]drm_file_free.part.7+0x273/0x2c0 [drm] [ 150.929680]drm_release+0x6e/0xf0 [drm] [ 150.929697]__fput+0xb2/0x260 [ 150.929714]task_work_run+0x73/0xc0 [ 150.929732]exit_to_user_mode_prepare+0x1a5/0x1d0 [ 150.929749]syscall_exit_to_user_mode+0x46/0x2a0 [ 150.929767]entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 150.929782] -> #1 (&cli->lock){+.+.}-{3:3}: [ 150.929811]__mutex_lock+0x90/0x9c0 [ 150.929936]nouveau_mem_fini+0x4c/0x70 [nouveau] [ 150.930062]nouveau_sgdma_destroy+0x20/0x50 [nouveau] [ 150.
[PATCH] firmware: arm_scmi: fix noderef.cocci warnings
From: kernel test robot drivers/firmware/arm_scmi/voltage.c:381:11-17: ERROR: application of sizeof to pointer sizeof when applied to a pointer typed expression gives the size of the pointer Generated by: scripts/coccinelle/misc/noderef.cocci CC: Cristian Marussi Signed-off-by: kernel test robot --- url: https://github.com/0day-ci/linux/commits/Cristian-Marussi/Add-support-for-SCMIv3-0-Voltage-Domain-Protocol-and-SCMI-Regulator/20201027-043404 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next voltage.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/drivers/firmware/arm_scmi/voltage.c +++ b/drivers/firmware/arm_scmi/voltage.c @@ -378,7 +378,7 @@ static int scmi_voltage_protocol_init(st if (vinfo->num_domains) { vinfo->domains = devm_kcalloc(handle->dev, vinfo->num_domains, - sizeof(vinfo->domains), + sizeof(*vinfo->domains), GFP_KERNEL); if (!vinfo->domains) return -ENOMEM;
Re: [PATCH v3 1/4] firmware: arm_scmi: Add Voltage Domain Support
Hi Cristian, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on soc/for-next] [also build test WARNING on next-20201026] [cannot apply to regulator/for-next robh/for-next rockchip/for-next keystone/next arm64/for-next/core linux/master linux-rpi/for-rpi-next at91/at91-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Cristian-Marussi/Add-support-for-SCMIv3-0-Voltage-Domain-Protocol-and-SCMI-Regulator/20201027-043404 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: arm-randconfig-c004-20201026 (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot "coccinelle warnings: (new ones prefixed by >>)" >> drivers/firmware/arm_scmi/voltage.c:381:11-17: ERROR: application of sizeof >> to pointer Please review and possibly fold the followup patch. --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
[PATCH v3] net: core: Use skb_is_gso() in skb_checksum_help()
No functional changes, just minor refactoring. Signed-off-by: Yi Li --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 82dc6b48e45f..9e7f071b846c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3206,7 +3206,7 @@ int skb_checksum_help(struct sk_buff *skb) if (skb->ip_summed == CHECKSUM_COMPLETE) goto out_set_summed; - if (unlikely(skb_shinfo(skb)->gso_size)) { + if (unlikely(skb_is_gso(skb))) { skb_warn_bad_offload(skb); return -EINVAL; } -- 2.25.3
Re: [PATCHv4] perf kvm: add kvm-stat for arm64
On (20/10/13 23:29), Leo Yan wrote: > On Tue, Oct 13, 2020 at 11:37:09AM -0300, Arnaldo Carvalho de Melo wrote: > > Em Tue, Sep 29, 2020 at 12:34:50PM +0900, Sergey Senozhatsky escreveu: > > > On (20/09/17 19:02), Sergey Senozhatsky wrote: > > > > Add support for perf kvm stat on arm64 platform. [..] > > > Arnaldo, any opinion on this? > > > > I'm not finding the actual patch, just this reply from you, lets try > > with b4 using this message Message-Id... Magic! But it isn't applying, > > can you please refresh the patch to what is in my perf/core branch? > > I did a quick trying, the merge confliction is caused by the file > tools/perf/arch/arm64/util/Build (for the new added tsc.c). > > @Sergey, please help to rebase on the latest perf/core branch [1]. Will do by the end of today! Sorry for the delay, somehow this whole followup conversation missed my inbox. -ss
Good News!!
You have a donation of £2,000,000.00 GBP from Frances & Patrick Connolly and Family. Reply to this email: (francespatrickconnol...@gmail.com) for more details. Please Note: This is the third time we have been trying to contact you. Best Regards Mrs. Mary Hamilton.
[PATCH v2 4/4] ALSA: hda: Reinstate runtime_allow() for all hda controllers
The broken jack detection should be fixed by commit a6e7d0a4bdb0 ("ALSA: hda: fix jack detection with Realtek codecs when in D3"), let's try enabling runtime PM by default again. Signed-off-by: Kai-Heng Feng --- v2: - No change. sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4cf90e4602c7..573250d2c6c9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2350,6 +2350,7 @@ static int azx_probe_continue(struct azx *chip) if (azx_has_pm_runtime(chip)) { pm_runtime_use_autosuspend(&pci->dev); + pm_runtime_allow(&pci->dev); pm_runtime_put_autosuspend(&pci->dev); } -- 2.17.1
[PATCH v2 0/4] HDA controller and PM cleanups
While working on the issue "ALSA: hda: fix jack detection with Realtek codecs when in D3", I've found using pm_runtime_force_{suspend,resume}() have surprising behavior, specifically, pm_runtime_need_not_resume() uses pm_runtime_need_not_resume() to avoid calling resume callback, so jackpoll was used to really power up the codec. We can use direct-complete to do the keep the codec suspended throughout the system PM flow, namely, keep the codec suspended all the way, unless the codec needs to be woken up after resume. For HDA controller, PCI core may enable direct-complete for it if conditions are met. So make runtime and system PM distinctive to always apply correct wake up setting. At least point, hopefully all runtime PM issues are solved, let's enable runtime PM by default again. Kai-Heng Feng (4): ALSA: hda: Refactor codec PM to use direct-complete optimization ALSA: hda: Stop mangling PCI IRQ ALSA: hda: Separate runtime and system suspend ALSA: hda: Reinstate runtime_allow() for all hda controllers sound/pci/hda/hda_codec.c | 45 +--- sound/pci/hda/hda_controller.h | 3 +- sound/pci/hda/hda_intel.c | 77 -- 3 files changed, 67 insertions(+), 58 deletions(-) -- 2.17.1
[PATCH v2 2/4] ALSA: hda: Stop mangling PCI IRQ
The code predates 2005, it should be unnecessary now as PCI core handles IRQ much better nowadays. So stop PCI IRQ mangling in suspend/resume callbacks. Takashi Iwai mentioned that IRQ number can change after S3 on some really old hardwares. We should use quirks to handle those platforms, as most modern systems won't have that issue. Signed-off-by: Kai-Heng Feng --- v2: - Wording. - Add info on IRQ # can change on old hardwares. sound/pci/hda/hda_intel.c | 15 --- 1 file changed, 15 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 749b88090970..b4aa1dcf1aae 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1022,13 +1022,11 @@ static int azx_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; - struct hdac_bus *bus; if (!azx_is_pm_ready(card)) return 0; chip = card->private_data; - bus = azx_bus(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); /* An ugly workaround: direct call of __azx_runtime_suspend() and * __azx_runtime_resume() for old Intel platforms that suffer from @@ -1038,14 +1036,6 @@ static int azx_suspend(struct device *dev) __azx_runtime_suspend(chip); else pm_runtime_force_suspend(dev); - if (bus->irq >= 0) { - free_irq(bus->irq, chip); - bus->irq = -1; - chip->card->sync_irq = -1; - } - - if (chip->msi) - pci_disable_msi(chip->pci); trace_azx_suspend(chip); return 0; @@ -1060,11 +1050,6 @@ static int azx_resume(struct device *dev) return 0; chip = card->private_data; - if (chip->msi) - if (pci_enable_msi(chip->pci) < 0) - chip->msi = 0; - if (azx_acquire_irq(chip, 1) < 0) - return -EIO; if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) __azx_runtime_resume(chip, false); -- 2.17.1
[PATCH v2 3/4] ALSA: hda: Separate runtime and system suspend
Both pm_runtime_force_suspend() and pm_runtime_force_resume() have some implicit checks, so it can make code flow more straightfoward if we separate runtime and systemd suspend callbacks. High Definition Audio Specification, 4.5.9.3 Codec Wake From System S3 states that codec can wake the system up from S3 if WAKEEN is toggled. Since HDA controller has different wakeup settings for runtime and system susend, we also need to explicitly disable direct-complete which can be enabled automatically by PCI core. In addition to that, avoid waking up codec if runtime resume is for system suspend, to not break direct-complete for codecs. While at it, also remove AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP, as the original bug commit a6630529aecb ("ALSA: hda: Workaround for spurious wakeups on some Intel platforms") solves doesn't happen with this patch. Signed-off-by: Kai-Heng Feng --- v2: - Make sure WAKEEN is disabled for system suspend. - Avoid waking up codec if runtime resume is for system suspend sound/pci/hda/hda_controller.h | 3 +- sound/pci/hda/hda_intel.c | 61 +++--- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index be63ead8161f..7176ef8170ba 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -41,7 +41,7 @@ /* 24 unused */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ -#define AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP (1 << 27) /* Workaround for spurious wakeups after suspend */ +/* 27 unused */ #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ #define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */ @@ -143,6 +143,7 @@ struct azx { unsigned int align_buffer_size:1; unsigned int region_requested:1; unsigned int disabled:1; /* disabled by vga_switcheroo */ + unsigned int prepared:1; /* GTS present */ unsigned int gts_present:1; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b4aa1dcf1aae..4cf90e4602c7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -297,8 +297,7 @@ enum { /* PCH for HSW/BDW; with runtime PM */ /* no i915 binding for this as HSW/BDW has another controller for HDMI */ #define AZX_DCAPS_INTEL_PCH \ - (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ -AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) + (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME) /* HSW HDMI */ #define AZX_DCAPS_INTEL_HASWELL \ @@ -1002,7 +1001,8 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt) azx_init_pci(chip); hda_intel_init_chip(chip, true); - if (from_rt) { + /* Avoid codec resume if runtime resume is for system suspend */ + if (from_rt && !chip->prepared) { list_for_each_codec(codec, &chip->bus) { if (codec->relaxed_resume) continue; @@ -1018,6 +1018,29 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt) } #ifdef CONFIG_PM_SLEEP +static int azx_prepare(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + struct azx *chip; + + chip = card->private_data; + chip->prepared = 1; + + /* HDA controller always requires different WAKEEN for runtime suspend +* and system suspend, so don't use direct-complete here. +*/ + return 0; +} + +static void azx_complete(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + struct azx *chip; + + chip = card->private_data; + chip->prepared = 0; +} + static int azx_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); @@ -1028,14 +1051,7 @@ static int azx_suspend(struct device *dev) chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - /* An ugly workaround: direct call of __azx_runtime_suspend() and -* __azx_runtime_resume() for old Intel platforms that suffer from -* spurious wakeups after S3 suspend -*/ - if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) - __azx_runtime_suspend(chip); - else - pm_runtime_force_suspend(dev); + __azx_runtime_suspend(chip); trace_azx_suspend(chip); return 0; @@ -1050,11 +1066,7 @@ static int azx_resume(struct device *dev) return 0; chip = card->private_data; - - if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) - __azx_runtime_resume(chip, false); - else - pm_runtime_force_resume(dev); + __azx_runtime_resume(chip, false); sn
[PATCH v2 1/4] ALSA: hda: Refactor codec PM to use direct-complete optimization
Upon system resume, hda_codec_pm_resume() uses hda_codec_force_resume() to resume the codec. However, pm_runtime_force_resume() won't really resume the codec because of pm_runtime_need_not_resume() check. Hence, hda_codec_force_resume() schedules a jackpoll work, which is to really power up the codec. Instead of doing that, we can use direct-complete to make the PM flow more straightforward, and keep codec always suspended through system PM flow if conditions are met. On system suspend, PM core will decide what to do based on hda_codec_pm_prepare(): - If codec is not runtime-suspended, PM core will suspend and resume the device as normal. - If codec is runtime-suspended, PM core will try to keep it suspended. If it's still suspended after system resume, we use hda_codec_pm_complete() to resume codec if it's needed. Signed-off-by: Kai-Heng Feng --- v2: - Also resume when codec->jackpoll_interval is set sound/pci/hda/hda_codec.c | 45 +-- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a356c21edb90..4bb58e8b08a8 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2934,7 +2934,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) snd_hdac_leave_pm(&codec->core); } -static int hda_codec_runtime_suspend(struct device *dev) +static int hda_codec_suspend(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); unsigned int state; @@ -2953,7 +2953,7 @@ static int hda_codec_runtime_suspend(struct device *dev) return 0; } -static int hda_codec_runtime_resume(struct device *dev) +static int hda_codec_resume(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); @@ -2967,57 +2967,70 @@ static int hda_codec_runtime_resume(struct device *dev) pm_runtime_mark_last_busy(dev); return 0; } + +static int hda_codec_runtime_suspend(struct device *dev) +{ + return hda_codec_suspend(dev); +} + +static int hda_codec_runtime_resume(struct device *dev) +{ + return hda_codec_resume(dev); +} + #endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP -static int hda_codec_force_resume(struct device *dev) +static int hda_codec_pm_prepare(struct device *dev) +{ + return pm_runtime_suspended(dev); +} + +static void hda_codec_pm_complete(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); - int ret; - ret = pm_runtime_force_resume(dev); - /* schedule jackpoll work for jack detection update */ - if (codec->jackpoll_interval || - (pm_runtime_suspended(dev) && hda_codec_need_resume(codec))) - schedule_delayed_work(&codec->jackpoll_work, - codec->jackpoll_interval); - return ret; + if (pm_runtime_suspended(dev) && (codec->jackpoll_interval || + hda_codec_need_resume(codec) || codec->forced_resume)) + pm_request_resume(dev); } static int hda_codec_pm_suspend(struct device *dev) { dev->power.power_state = PMSG_SUSPEND; - return pm_runtime_force_suspend(dev); + return hda_codec_suspend(dev); } static int hda_codec_pm_resume(struct device *dev) { dev->power.power_state = PMSG_RESUME; - return hda_codec_force_resume(dev); + return hda_codec_resume(dev); } static int hda_codec_pm_freeze(struct device *dev) { dev->power.power_state = PMSG_FREEZE; - return pm_runtime_force_suspend(dev); + return hda_codec_suspend(dev); } static int hda_codec_pm_thaw(struct device *dev) { dev->power.power_state = PMSG_THAW; - return hda_codec_force_resume(dev); + return hda_codec_resume(dev); } static int hda_codec_pm_restore(struct device *dev) { dev->power.power_state = PMSG_RESTORE; - return hda_codec_force_resume(dev); + return hda_codec_resume(dev); } #endif /* CONFIG_PM_SLEEP */ /* referred in hda_bind.c */ const struct dev_pm_ops hda_codec_driver_pm = { #ifdef CONFIG_PM_SLEEP + .prepare = hda_codec_pm_prepare, + .complete = hda_codec_pm_complete, .suspend = hda_codec_pm_suspend, .resume = hda_codec_pm_resume, .freeze = hda_codec_pm_freeze, -- 2.17.1
[PATCH v4 2/2] f2fs: add F2FS_IOC_SET_COMPRESS_OPTION ioctl
From: Daeho Jeong Added a new F2FS_IOC_SET_COMPRESS_OPTION ioctl to change file compression option of a file. struct f2fs_comp_option { u8 algorithm; => compression algorithm => 0:lzo, 1:lz4, 2:zstd, 3:lzorle u8 log_cluster_size; => log scale cluster size => 2 ~ 8 }; struct f2fs_comp_option option; option.algorithm = 1; option.log_cluster_size = 7; ioctl(fd, F2FS_IOC_SET_COMPRESS_OPTION, &option); Signed-off-by: Daeho Jeong --- v4: changed commit message. v3: changed the error number more specific. folded in fix for build breakage reported by kernel test robot and Dan Carpenter . v2: added ioctl description. --- fs/f2fs/compress.c | 5 + fs/f2fs/f2fs.h | 7 +++ fs/f2fs/file.c | 52 ++ 3 files changed, 64 insertions(+) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 7895186cc765..816d7adc914c 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -514,6 +514,11 @@ bool f2fs_is_compress_backend_ready(struct inode *inode) return f2fs_cops[F2FS_I(inode)->i_compress_algorithm]; } +bool f2fs_is_compress_algorithm_ready(unsigned char algorithm) +{ + return algorithm < COMPRESS_MAX && f2fs_cops[algorithm] != NULL; +} + static mempool_t *compress_page_pool; static int num_compress_pages = 512; module_param(num_compress_pages, uint, 0444); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a33c90cf979b..cc38afde6c04 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -435,6 +435,8 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal, struct f2fs_sectrim_range) #define F2FS_IOC_GET_COMPRESS_OPTION _IOR(F2FS_IOCTL_MAGIC, 21, \ struct f2fs_comp_option) +#define F2FS_IOC_SET_COMPRESS_OPTION _IOW(F2FS_IOCTL_MAGIC, 22, \ + struct f2fs_comp_option) /* * should be same as XFS_IOC_GOINGDOWN. @@ -3915,6 +3917,7 @@ bool f2fs_compress_write_end(struct inode *inode, void *fsdata, int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock); void f2fs_compress_write_end_io(struct bio *bio, struct page *page); bool f2fs_is_compress_backend_ready(struct inode *inode); +bool f2fs_is_compress_algorithm_ready(unsigned char algorithm); int f2fs_init_compress_mempool(void); void f2fs_destroy_compress_mempool(void); void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity); @@ -3945,6 +3948,10 @@ static inline bool f2fs_is_compress_backend_ready(struct inode *inode) /* not support compression */ return false; } +static inline bool f2fs_is_compress_algorithm_ready(unsigned char algorithm) +{ + return false; +} static inline struct page *f2fs_compress_control_page(struct page *page) { WARN_ON_ONCE(1); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 8922ab191a9d..8048b150e43b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3963,6 +3963,55 @@ static int f2fs_ioc_get_compress_option(struct file *filp, unsigned long arg) return 0; } +static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_comp_option option; + int ret = 0; + + if (!f2fs_sb_has_compression(sbi)) + return -EOPNOTSUPP; + + if (!(filp->f_mode & FMODE_WRITE)) + return -EBADF; + + if (copy_from_user(&option, (struct f2fs_comp_option __user *)arg, + sizeof(option))) + return -EFAULT; + + if (!f2fs_compressed_file(inode) || + option.log_cluster_size < MIN_COMPRESS_LOG_SIZE || + option.log_cluster_size > MAX_COMPRESS_LOG_SIZE) + return -EINVAL; + + if (!f2fs_is_compress_algorithm_ready(option.algorithm)) + return -ENOPKG; + + file_start_write(filp); + inode_lock(inode); + + if (f2fs_is_mmap_file(inode) || get_dirty_pages(inode)) { + ret = -EBUSY; + goto out; + } + + if (inode->i_size != 0) { + ret = -EFBIG; + goto out; + } + + F2FS_I(inode)->i_compress_algorithm = option.algorithm; + F2FS_I(inode)->i_log_cluster_size = option.log_cluster_size; + F2FS_I(inode)->i_cluster_size = 1 << option.log_cluster_size; + f2fs_mark_inode_dirty_sync(inode, true); +out: + inode_unlock(inode); + file_end_write(filp); + + return ret; +} + long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp) @@ -4053,6 +4102,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_s
[PATCH v4 1/2] f2fs: add F2FS_IOC_GET_COMPRESS_OPTION ioctl
From: Daeho Jeong Added a new F2FS_IOC_GET_COMPRESS_OPTION ioctl to get file compression option of a file. struct f2fs_comp_option { u8 algorithm; => compression algorithm => 0:lzo, 1:lz4, 2:zstd, 3:lzorle u8 log_cluster_size; => log scale cluster size => 2 ~ 8 }; struct f2fs_comp_option option; ioctl(fd, F2FS_IOC_GET_COMPRESS_OPTION, &option); Signed-off-by: Daeho Jeong --- v4: changed commit message. v3: changed the error number more specific. v2: added ioctl description. --- fs/f2fs/f2fs.h | 7 +++ fs/f2fs/file.c | 30 ++ 2 files changed, 37 insertions(+) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 53fe2853579c..a33c90cf979b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -433,6 +433,8 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal, _IOR(F2FS_IOCTL_MAGIC, 19, __u64) #define F2FS_IOC_SEC_TRIM_FILE _IOW(F2FS_IOCTL_MAGIC, 20, \ struct f2fs_sectrim_range) +#define F2FS_IOC_GET_COMPRESS_OPTION _IOR(F2FS_IOCTL_MAGIC, 21, \ + struct f2fs_comp_option) /* * should be same as XFS_IOC_GOINGDOWN. @@ -481,6 +483,11 @@ struct f2fs_sectrim_range { u64 flags; }; +struct f2fs_comp_option { + u8 algorithm; + u8 log_cluster_size; +}; + /* for inline stuff */ #define DEF_INLINE_RESERVED_SIZE 1 static inline int get_extra_isize(struct inode *inode); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index ef5a844de53f..8922ab191a9d 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3936,6 +3936,33 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg) return ret; } +static int f2fs_ioc_get_compress_option(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_comp_option option; + + if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) + return -EOPNOTSUPP; + + inode_lock(inode); + + if (!f2fs_compressed_file(inode)) { + inode_unlock(inode); + return -ENODATA; + } + + option.algorithm = F2FS_I(inode)->i_compress_algorithm; + option.log_cluster_size = F2FS_I(inode)->i_log_cluster_size; + + inode_unlock(inode); + + if (copy_to_user((struct f2fs_comp_option __user *)arg, &option, + sizeof(option))) + return -EFAULT; + + return 0; +} + long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp) @@ -4024,6 +4051,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_reserve_compress_blocks(filp, arg); case F2FS_IOC_SEC_TRIM_FILE: return f2fs_sec_trim_file(filp, arg); + case F2FS_IOC_GET_COMPRESS_OPTION: + return f2fs_ioc_get_compress_option(filp, arg); default: return -ENOTTY; } @@ -4194,6 +4223,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case F2FS_IOC_RELEASE_COMPRESS_BLOCKS: case F2FS_IOC_RESERVE_COMPRESS_BLOCKS: case F2FS_IOC_SEC_TRIM_FILE: + case F2FS_IOC_GET_COMPRESS_OPTION: break; default: return -ENOIOCTLCMD; -- 2.29.0.rc2.309.g374f81d7ae-goog
[PATCH] bus: mhi: core: Fix null pointer access
From: carl function parse_ev_cfg and parse_ch_cfg access mhi_cntrl->mhi_dev before it is set in function mhi_register_controller, use cntrl_dev to instead mhi_dev. Signed-off-by: carl --- drivers/bus/mhi/core/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 0ffdebde8..c6b43e90b 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -610,7 +610,7 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, { struct mhi_event *mhi_event; const struct mhi_event_config *event_cfg; - struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct device *dev = mhi_cntrl->cntrl_dev; int i, num; num = config->num_events; @@ -692,7 +692,7 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, const struct mhi_controller_config *config) { const struct mhi_channel_config *ch_cfg; - struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct device *dev = mhi_cntrl->cntrl_dev; int i; u32 chan; -- 2.17.1
[rcu:dev.2020.10.22a] BUILD SUCCESS e8b795e5dd23eaf0f7e9e75121d82a16f1c722db
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev.2020.10.22a branch HEAD: e8b795e5dd23eaf0f7e9e75121d82a16f1c722db kcsan: Never set up watchpoints on NULL pointers elapsed time: 720m configs tested: 107 configs skipped: 2 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm defconfig arm64allyesconfig arm64 defconfig arm allyesconfig arm allmodconfig sh landisk_defconfig powerpc obs600_defconfig mips decstation_defconfig arm sama5_defconfig m68k m5249evb_defconfig mipsmaltaup_xpa_defconfig sh secureedge5410_defconfig mips rbtx49xx_defconfig sh sh7710voipgw_defconfig powerpc mpc85xx_cds_defconfig sh rsk7264_defconfig ia64defconfig riscvallyesconfig powerpc sbc8548_defconfig arm exynos_defconfig xtensa virt_defconfig mips bmips_stb_defconfig pariscgeneric-32bit_defconfig arm integrator_defconfig arm simpad_defconfig sh espt_defconfig arm iop32x_defconfig xtensa defconfig armmulti_v7_defconfig xtensa nommu_kc705_defconfig arc axs101_defconfig powerpc linkstation_defconfig c6x defconfig sh j2_defconfig mipsgpr_defconfig shmigor_defconfig arm stm32_defconfig powerpcgamecube_defconfig arm assabet_defconfig mips pistachio_defconfig ia64 allmodconfig ia64 allyesconfig m68k allmodconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig c6x allyesconfig nds32 defconfig nios2allyesconfig cskydefconfig alpha defconfig alphaallyesconfig xtensa allyesconfig h8300allyesconfig arc defconfig sh allmodconfig parisc defconfig s390 allyesconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig i386 randconfig-a002-20201026 i386 randconfig-a003-20201026 i386 randconfig-a005-20201026 i386 randconfig-a001-20201026 i386 randconfig-a006-20201026 i386 randconfig-a004-20201026 x86_64 randconfig-a011-20201026 x86_64 randconfig-a013-20201026 x86_64 randconfig-a016-20201026 x86_64 randconfig-a015-20201026 x86_64 randconfig-a012-20201026 x86_64 randconfig-a014-20201026 i386 randconfig-a016-20201026 i386 randconfig-a015-20201026 i386 randconfig-a014-20201026 i386 randconfig-a012-20201026 i386 randconfig-a013-20201026 i386 randconfig-a011-20201026 riscvnommu_k210_defconfig riscvnommu_virt_defconfig riscv allnoconfig riscv defconfig riscv rv32_defconfig riscvallmodconfig x86_64 rhel x86_64 allyesconfig x86_64rhel-7.6-kselftests x86_64 defconfig x86_64 rhel-8.3 x86_64
linux-next: Tree for Oct 27
Hi all, Changes since 20201026: Removed trees: unifier-fixes, unifier (no longer maintained) The sunxi tree gained a build failure for which I reverted a commit. The vfs tree gained a bad merge for which I added a fix patch. The v4l-dvb-next tree gained a conflict against the kunit-fixes tree. The amdgpu tree gained a conflict against Linus' tree and a build failure so I used the version from next-20201026. The drm-misc tree gained conflicts against Linus' tree. Non-merge commits (relative to Linus' tree): 1177 1552 files changed, 307467 insertions(+), 15104 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc and sparc64 defconfig and htmldocs. And finally, a simple boot test of the powerpc pseries_le_defconfig kernel in qemu (with and without kvm enabled). Below is a summary of the state of the merge. I am currently merging 327 trees (counting Linus' and 85 trees of bug fix patches pending for the current merge release). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (41ba50b0572e Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6) Merging fixes/fixes (9123e3a74ec7 Linux 5.9-rc1) Merging kbuild-current/fixes (f11901ed723d Merge tag 'xfs-5.10-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux) Merging arc-current/for-curr (3650b228f83a Linux 5.10-rc1) Merging arm-current/fixes (9123e3a74ec7 Linux 5.9-rc1) Merging arm64-fixes/for-next/fixes (0fa97e9403c7 arm64: vdso32: Allow ld.lld to properly link the VDSO) Merging arm-soc-fixes/arm/fixes (dff61e683e74 Merge tag 'imx-fixes-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/fixes) Merging drivers-memory-fixes/fixes (3650b228f83a Linux 5.10-rc1) Merging m68k-current/for-linus (50c5feeea0af ide/macide: Convert Mac IDE driver to platform driver) Merging powerpc-fixes/fixes (4ff753feab02 powerpc/pseries: Avoid using addr_to_pfn in real mode) Merging s390-fixes/fixes (8e90b4b1305a s390: correct __bootdata / __bootdata_preserved macros) Merging sparc/master (0a95a6d1a4cd sparc: use for_each_child_of_node() macro) Merging fscrypt-current/for-stable (2b4eae95c736 fscrypt: don't evict dirty inodes after removing key) Merging net/master (435ccfa894e3 tcp: Prevent low rmem stalls with SO_RCVLOWAT.) Merging bpf/master (472547778de2 selftest/bpf: Fix profiler test using CO-RE relocation for enums) Merging ipsec/master (a779d91314ca net: xfrm: fix a race condition during allocing spi) Merging netfilter/master (c77761c8a594 netfilter: nf_fwd_netdev: clear timestamp in forwarding path) Merging ipvs/master (48d072c4e8cd selftests: netfilter: add time counter check) Merging wireless-drivers/master (3650b228f83a Linux 5.10-rc1) Merging mac80211/master (435ccfa894e3 tcp: Prevent low rmem stalls with SO_RCVLOWAT.) Merging rdma-fixes/for-rc (3650b228f83a Linux 5.10-rc1) Merging sound-current/for-linus (2a6eca16f376 ALSA: make snd_kcontrol_new name a normal string) Merging sound-asoc-fixes/for-linus (8099fe48df2c Merge remote-tracking branch 'asoc/for-5.10' into asoc-linus) Merging regmap-fixes/for-linus (3493d90df3aa Merge remote-tracking branch 'regmap/for-5.10' into regmap-linus) Merging regulator-fixes/for-linus (dc3afaa95f47 Merge remote-tracking branch 'regulator/for-5.10' into regulator-linus) Merging spi-fixes/for-linus (91cbcc28a2ee Merge remote-tracking branch 'spi/for-5.10' into spi-linus) Merging pci-current/for-linus (3650
[tip:x86/cleanups] BUILD SUCCESS 3adb776384f2042ef6bda876e91a7a7ac2872c5e
allyesconfig arc defconfig sh allmodconfig parisc defconfig s390 allyesconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig i386 randconfig-a002-20201026 i386 randconfig-a003-20201026 i386 randconfig-a005-20201026 i386 randconfig-a001-20201026 i386 randconfig-a006-20201026 i386 randconfig-a004-20201026 x86_64 randconfig-a011-20201026 x86_64 randconfig-a013-20201026 x86_64 randconfig-a016-20201026 x86_64 randconfig-a015-20201026 x86_64 randconfig-a012-20201026 x86_64 randconfig-a014-20201026 i386 randconfig-a016-20201026 i386 randconfig-a015-20201026 i386 randconfig-a014-20201026 i386 randconfig-a012-20201026 i386 randconfig-a013-20201026 i386 randconfig-a011-20201026 riscvnommu_k210_defconfig riscvallyesconfig riscvnommu_virt_defconfig riscv allnoconfig riscv defconfig riscv rv32_defconfig riscvallmodconfig x86_64 rhel x86_64rhel-7.6-kselftests x86_64 defconfig x86_64 rhel-8.3 x86_64 kexec clang tested configs: x86_64 randconfig-a001-20201026 x86_64 randconfig-a003-20201026 x86_64 randconfig-a002-20201026 x86_64 randconfig-a006-20201026 x86_64 randconfig-a004-20201026 x86_64 randconfig-a005-20201026 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
RE: [PATCH] ath10k: add option for chip-id based BDF selection
> -Original Message- > From: Doug Anderson > Sent: Tuesday, October 27, 2020 4:21 AM > To: Rakesh Pillai > Cc: Abhishek Kumar ; Kalle Valo > ; ath10k ; LKML > ; linux-wireless wirel...@vger.kernel.org>; Brian Norris > Subject: Re: [PATCH] ath10k: add option for chip-id based BDF selection > > Hi, > > On Sat, Oct 24, 2020 at 9:40 AM Rakesh Pillai wrote: > > > > > if (bd_ie_type == ATH10K_BD_IE_BOARD) { > > > + /* With variant and chip id */ > > > ret = ath10k_core_create_board_name(ar, boardname, > > > - sizeof(boardname), > > > true); > > > + sizeof(boardname), true, > > > true); > > > > Instead of adding a lot of code to generate a second fallback name, its > better to just modify the condition inside the function > “ath10k_core_create_board_name” to allow the generation of BDF tag using > chip id, even “if ar->id.bdf_ext[0] == '\0 “. > > > > This will make sure that the variant string is NULL, and just board-id and > chip-id is used. This will help avoid most of the code changes. > > The code would look as shown below > > > > @@ -1493,7 +1493,7 @@ static int ath10k_core_create_board_name(struct > ath10k *ar, char *name, > > } > > > > if (ar->id.qmi_ids_valid) { > > - if (with_variant && ar->id.bdf_ext[0] != '\0') > > + if (with_variant) > > Wouldn't the above just be "if (with_chip_id)" instead? ...but yeah, > that would be a cleaner way to do this. Abhishek: do you want to post > a v2? The parameter name passed to this function is "with_variant", since other non-qmi targets (eg QCA6174) use this as a flag to just add the variant field. This can be renamed to something meaningful for both qmi and non-qmi targets. > > -Doug
Re: [PATCH v3 1/2] kunit: Support for Parameterized Testing
On 27/10/20 4:44 am, Marco Elver wrote: > On Mon, 26 Oct 2020 at 19:36, Arpitha Raghunandan <98.a...@gmail.com> wrote: >> >> Implementation of support for parameterized testing in KUnit. >> This approach requires the creation of a test case using the >> KUNIT_CASE_PARAM macro that accepts a generator function as input. >> This generator function should return the next parameter given the >> previous parameter in parameterized tests. It also provides >> a macro to generate common-case generators. >> >> Signed-off-by: Arpitha Raghunandan <98.a...@gmail.com> >> Co-developed-by: Marco Elver >> Signed-off-by: Marco Elver >> --- >> Changes v2->v3: >> - Modifictaion of generator macro and method > > Great to see it worked as expected! > >> Changes v1->v2: >> - Use of a generator method to access test case parameters >> >> include/kunit/test.h | 32 >> lib/kunit/test.c | 20 +++- >> 2 files changed, 51 insertions(+), 1 deletion(-) >> >> diff --git a/include/kunit/test.h b/include/kunit/test.h >> index a423fffefea0..16bf9f334e2c 100644 >> --- a/include/kunit/test.h >> +++ b/include/kunit/test.h >> @@ -142,6 +142,12 @@ struct kunit_case { >> void (*run_case)(struct kunit *test); >> const char *name; >> >> + /* >> +* Pointer to test parameter generator function. >> +* Used only for parameterized tests. > > What I meant was to give a description of the protocol, so that if > somebody wanted, they could (without reading the implementation) > implement their own custom generator without the helper macro. > > E.g. something like: "The generator function is used to lazily > generate a series of arbitrarily typed values that fit into a void*. > The argument @prev is the previously returned value, which should be > used to derive the next value; @prev is set to NULL on the initial > generator call. When no more values are available, the generator must > return NULL." > Oh okay. I am not sure if this is the best place to add documentation for this. >> +*/ >> + void* (*generate_params)(void *prev); >> + >> /* private: internal use only. */ >> bool success; >> char *log; >> @@ -162,6 +168,9 @@ static inline char *kunit_status_to_string(bool status) >> * &struct kunit_case for an example on how to use it. >> */ >> #define KUNIT_CASE(test_name) { .run_case = test_name, .name = #test_name } >> +#define KUNIT_CASE_PARAM(test_name, gen_params)\ >> + { .run_case = test_name, .name = #test_name,\ >> + .generate_params = gen_params } >> >> /** >> * struct kunit_suite - describes a related collection of &struct kunit_case >> @@ -208,6 +217,15 @@ struct kunit { >> const char *name; /* Read only after initialization! */ >> char *log; /* Points at case log after initialization */ >> struct kunit_try_catch try_catch; >> + /* param_values points to test case parameters in parameterized >> tests */ >> + void *param_values; >> + /* >> +* current_param stores the index of the parameter in >> +* the array of parameters in parameterized tests. >> +* current_param + 1 is printed to indicate the parameter >> +* that causes the test to fail in case of test failure. >> +*/ >> + int current_param; >> /* >> * success starts as true, and may only be set to false during a >> * test case; thus, it is safe to update this across multiple >> @@ -1742,4 +1760,18 @@ do { >> \ >> fmt, >> \ >> ##__VA_ARGS__) >> >> +/** >> + * KUNIT_PARAM_GENERATOR() - Helper method for test parameter generators >> + * required in parameterized tests. > > This is only for arrays, which is why I suggested KUNIT_ARRAY_PARAM() > as the name. > > A generator can very well be implemented without an array, so this > macro name is confusing. In future somebody might want to provide a > macro that takes a start + end value (and maybe a step value) to > generate a series of values. That generator could be named > KUNIT_RANGE_PARAM(name, start, end, step) and gives us a generator > that is also named name##_gen_params. (If you want to try implementing > that macro, I'd suggest doing it as a separate patch.) > > And I don't think we need to put "GENERATOR" into the name of these > macros, because the generators are now the fundamental method with > which to get parameterized tests. We don't need to state the obvious, > in favor of some brevity. > Okay, makes sense. I will change it to KUNIT_ARRAY_PARAM() for the next version. >> + * @name: prefix of the name for the test parameter generator function. >> + * @prev: a pointer to the previous test para
Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
On 26-10-20, 01:17, Dmitry Osipenko wrote: > This patch fixes lockup which happens when OPP table is released if > interconnect provider uses OPP in the icc_provider->set() callback > and bandwidth of the ICC path is set to 0 by the ICC core when path > is released. The icc_put() doesn't need the opp_table_lock protection, > hence let's move it outside of the lock in order to resolve the problem. > > In particular this fixes tegra-devfreq driver lockup on trying to unload > the driver module. The devfreq driver uses OPP-bandwidth API and its ICC > provider also uses OPP for DVFS, hence they both take same opp_table_lock > when OPP table of the devfreq is released. > > Signed-off-by: Dmitry Osipenko > --- > drivers/opp/core.c | 21 ++--- > 1 file changed, 14 insertions(+), 7 deletions(-) > > diff --git a/drivers/opp/core.c b/drivers/opp/core.c > index 2483e765318a..1134df360fe0 100644 > --- a/drivers/opp/core.c > +++ b/drivers/opp/core.c > @@ -1187,12 +1187,6 @@ static void _opp_table_kref_release(struct kref *kref) > if (!IS_ERR(opp_table->clk)) > clk_put(opp_table->clk); > > - if (opp_table->paths) { > - for (i = 0; i < opp_table->path_count; i++) > - icc_put(opp_table->paths[i]); > - kfree(opp_table->paths); > - } > - > WARN_ON(!list_empty(&opp_table->opp_list)); > > list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) { > @@ -1209,9 +1203,22 @@ static void _opp_table_kref_release(struct kref *kref) > mutex_destroy(&opp_table->genpd_virt_dev_lock); > mutex_destroy(&opp_table->lock); > list_del(&opp_table->node); > - kfree(opp_table); > > mutex_unlock(&opp_table_lock); > + > + /* > + * Interconnect provider may use OPP too, hence icc_put() needs to be > + * invoked outside of the opp_table_lock in order to prevent nested > + * locking which happens when bandwidth of the ICC path is set to 0 > + * by ICC core on release of the path. > + */ > + if (opp_table->paths) { > + for (i = 0; i < opp_table->path_count; i++) > + icc_put(opp_table->paths[i]); > + kfree(opp_table->paths); > + } > + > + kfree(opp_table); > } Never make such _fixes_ part of such a big patchset. Always send them separately. Having said that, I already have a patch with me which shall fix it for you as well: diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 4ac4e7ce6b8b..0e0a5269dc82 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1181,6 +1181,10 @@ static void _opp_table_kref_release(struct kref *kref) struct opp_device *opp_dev, *temp; int i; + /* Drop the lock as soon as we can */ + list_del(&opp_table->node); + mutex_unlock(&opp_table_lock); + _of_clear_opp_table(opp_table); /* Release clk */ @@ -1208,10 +1212,7 @@ static void _opp_table_kref_release(struct kref *kref) mutex_destroy(&opp_table->genpd_virt_dev_lock); mutex_destroy(&opp_table->lock); - list_del(&opp_table->node); kfree(opp_table); - - mutex_unlock(&opp_table_lock); } void dev_pm_opp_put_opp_table(struct opp_table *opp_table) -- viresh
Re: [PATCH v2] perf trace: Segfault when trying to trace events by cgroup
Hello, On Mon, Oct 26, 2020 at 10:21 PM Stanislav Ivanichkin wrote: > > v2: > - struct declaration fixed (Namhyung Kim) > > Fixes: 9ea42ba4411ac ("perf trace: Support setting cgroups as targets") > Signed-off-by: Stanislav Ivanichkin Looks ok but you'd better add the commit description in v1. Acked-by: Namhyung Kim Thanks Namhyung > --- > tools/perf/builtin-trace.c | 15 +-- > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c > index 44a75f234db1..de80534473af 100644 > --- a/tools/perf/builtin-trace.c > +++ b/tools/perf/builtin-trace.c > @@ -4639,9 +4639,9 @@ static int trace__parse_events_option(const struct > option *opt, const char *str, > err = 0; > > if (lists[0]) { > - struct option o = OPT_CALLBACK('e', "event", &trace->evlist, > "event", > - "event selector. use 'perf > list' to list available events", > - parse_events_option); > + struct option o = { > + .value = &trace->evlist, > + }; > err = parse_events_option(&o, lists[0], 0); > } > out: > @@ -4655,9 +4655,12 @@ static int trace__parse_cgroups(const struct option > *opt, const char *str, int u > { > struct trace *trace = opt->value; > > - if (!list_empty(&trace->evlist->core.entries)) > - return parse_cgroups(opt, str, unset); > - > + if (!list_empty(&trace->evlist->core.entries)) { > + struct option o = { > + .value = &trace->evlist, > + }; > + return parse_cgroups(&o, str, unset); > + } > trace->cgroup = evlist__findnew_cgroup(trace->evlist, str); > > return 0; > -- > 2.17.1 >
Re: Perf raw sample overflows perf record
+ LKML On Sat, Oct 24, 2020 at 8:44 AM George Prekas wrote: > > The header of a perf sample has a u16 field for the size of the record. > On the other hand, a PERF_SAMPLE_RAW has a u32 field for its size. > > I've written a test perf driver that creates large raw samples and it > doesn't work correctly (as expected). For example, perf record fails with: > > Can't parse sample, err = -14 > 0x4688 [0x8]: failed to process type: 68 [Bad address] > > Is this expected? Is the developer of the perf driver responsible to > make sure that each perf record does not exceed 64KB in size? If that's > the case, I am wondering why the raw sample has a u32 for its size. For the large records, you may consider an auxtrace interface. Thanks Namhyung
Re: [Regression] "tpm: Require that all digests are present in TCG_PCR_EVENT2 structures" causes null pointer dereference
On 2020-10-26 13:49:59, Kai-Heng Feng wrote: > > > > On Oct 21, 2020, at 13:48, Tyler Hicks wrote: > > > > On 2020-10-20 17:07:50, Mimi Zohar wrote: > >> On Tue, 2020-09-29 at 13:52 -0400, Mimi Zohar wrote: > >>> On Mon, 2020-09-28 at 22:16 +0800, Kai-Heng Feng wrote: > Hi Jarkko, > > > On Sep 28, 2020, at 22:06, Jarkko Sakkinen > > wrote: > > > > On Mon, Sep 28, 2020 at 08:31:04PM +0800, Kai-Heng Feng wrote: > >> Commit 7f3d176f5f7e "tpm: Require that all digests are present in > >> TCG_PCR_EVENT2 structures" causes a null pointer dereference on all > >> laptops I have: > > > > ... > > > >> [ 17.868849] BUG: kernel NULL pointer dereference, address: > >> 002c > >> [ 17.868852] #PF: supervisor read access in kernel mode > >> [ 17.868854] #PF: error_code(0x) - not-present page > >> [ 17.868855] PGD 0 P4D 0 > >> [ 17.868858] Oops: [#1] SMP PTI > >> [ 17.868860] CPU: 0 PID: 1873 Comm: fwupd Not tainted 5.8.0-rc6+ #25 > >> [ 17.868861] Hardware name: LENOVO 20LAZ3TXCN/20LAZ3TXCN, BIOS > >> N27ET38W (1.24 ) 11/28/2019 > >> [ 17.868866] RIP: 0010:tpm2_bios_measurements_start+0x38/0x1f0 > >> [ 17.868868] Code: 55 41 54 53 48 83 ec 30 4c 8b 16 65 48 8b 04 25 > >> 28 00 00 00 48 89 45 d0 48 8b 47 70 4c 8b a0 d0 06 00 00 48 8b 88 d8 > >> 06 00 00 <41> 8b 5c 24 1c 48 89 4d b0 48 89 d8 48 83 c3 20 4d 85 d2 75 > >> 31 4c > >> [ 17.868869] RSP: 0018:9da500a9fde0 EFLAGS: 00010282 > >> [ 17.868871] RAX: 917d03dc4000 RBX: RCX: > >> 0010 > >> [ 17.868872] RDX: 1000 RSI: 917c99b19460 RDI: > >> 917c99b19438 > >> [ 17.868873] RBP: 9da500a9fe38 R08: bda4ffa33fc0 R09: > >> 917cbfeae4c0 > >> [ 17.868874] R10: R11: 0002 R12: > >> 0010 > >> [ 17.868875] R13: 917c99b19438 R14: 917c99b19460 R15: > >> 917c99b19470 > >> [ 17.868876] FS: 7f9d80988b00() GS:917d0740() > >> knlGS: > >> [ 17.868877] CS: 0010 DS: ES: CR0: 80050033 > >> [ 17.868878] CR2: 002c CR3: 000219b12004 CR4: > >> 003606f0 > >> [ 17.868879] Call Trace: > >> [ 17.868884] seq_read+0x95/0x470 > >> [ 17.868887] ? security_file_permission+0x150/0x160 > >> [ 17.868889] vfs_read+0xaa/0x190 > >> [ 17.868891] ksys_read+0x67/0xe0 > >> [ 17.868893] __x64_sys_read+0x1a/0x20 > >> [ 17.868896] do_syscall_64+0x52/0xc0 > >> [ 17.868898] entry_SYSCALL_64_after_hwframe+0x44/0xa9 > >> [ 17.868900] RIP: 0033:0x7f9d83be91dc > >> [ 17.868901] Code: Bad RIP value. > >> [ 17.868902] RSP: 002b:7fff7f5e0250 EFLAGS: 0246 ORIG_RAX: > >> > >> [ 17.868903] RAX: ffda RBX: 5651d262f420 RCX: > >> 7f9d83be91dc > >> [ 17.868904] RDX: 1000 RSI: 7fff7f5e0350 RDI: > >> 0010 > >> [ 17.868905] RBP: 7f9d83cc54a0 R08: R09: > >> 5651d26c1830 > >> [ 17.868906] R10: 5651d2582010 R11: 0246 R12: > >> 1000 > >> [ 17.868907] R13: 7fff7f5e0350 R14: 0d68 R15: > >> 7f9d83cc48a0 > >> [ 17.868909] Modules linked in: rfcomm ccm cmac algif_hash > >> algif_skcipher af_alg snd_hda_codec_hdmi snd_hda_codec_realtek > >> snd_hda_codec_generic bnep joydev mei_hdcp wmi_bmof intel_rapl_msr > >> intel_wmi_thunderbolt x86_pkg_temp_thermal intel_powerclamp coretemp > >> nls_iso8859_1 kvm_intel kvm crct10dif_pclmul crc32_pclmul > >> ghash_clmulni_intel aesni_intel glue_helper crypto_simd cryptd rapl > >> input_leds intel_cstate snd_hda_intel snd_intel_dspcfg rmi_smbus > >> iwlmvm snd_hda_codec serio_raw snd_hwdep mac80211 rmi_core > >> snd_hda_core libarc4 uvcvideo snd_pcm videobuf2_vmalloc btusb > >> videobuf2_memops iwlwifi videobuf2_v4l2 btrtl btbcm videobuf2_common > >> btintel thunderbolt i915 bluetooth mei_me videodev thinkpad_acpi nvram > >> cfg80211 ledtrig_audio mei mc ecdh_generic ecc i2c_algo_bit > >> processor_thermal_device snd_seq_midi drm_kms_helper > >> snd_seq_midi_event intel_soc_dts_iosf syscopyarea sysfillrect > >> snd_rawmidi intel_pch_thermal sysimgblt intel_rapl_common > >> intel_xhci_usb_role_switch fb_sys_fops > >> u > >>> cs > i_acpi r > o > > les cec > >> [ 17.868935] typec_ucsi typec nxp_nci_i2c snd_seq nxp_nci wmi nci > >> nfc snd_timer snd_seq_device snd int3403_thermal soundcore > >> int340x_thermal_zone video mac_hid int3400_thermal acpi_pad > >> acpi_thermal_rel sch_fq_codel parport_pc ppdev lp parport drm > >> ip_tables x_tables autofs4 btrfs blake2b_generic libcrc3
Re: [PATCH v2 2/2] perf stat: Support regex pattern in --for-each-cgroup
Hi Arnaldo, On Tue, Oct 27, 2020 at 2:53 AM Arnaldo Carvalho de Melo wrote: > > Em Mon, Oct 26, 2020 at 09:32:34PM +0900, Namhyung Kim escreveu: > > Hi Jiri, > > > > On Mon, Oct 26, 2020 at 8:40 PM Jiri Olsa wrote: > > > also perhaps we want to warn if there's no match found: > > > > > > $ sudo ./perf stat -a -e cpu-clock,cycles --for-each-cgroup ^foo > > > sleep 1 > > > > > > Performance counter stats for 'system wide': > > > > > > > > >1.002375575 seconds time elapsed > > > > > > > Right, will check this case. > > Hum, I thought that could be done on top of this one, but then, the > ambiguity of: > > 1. No samples for a cgroups matching that expression > > 2. No cgroups match that expression > > Is real and warrants a warning for the 'no cgroups match the > --for-each-group regexp' case. The 1 will be handled by perf stat showing and I'll add a warning for the item 2 like below: # perf stat -a -e cycles --for-each-cgroup ^foo sleep 1 no cgroup matched: ^foo Usage: perf stat [] [] --for-each-cgroup expand events for each cgroup Thanks Namhyung
Re: linux-next: build failure after merge of the vfs tree
On Tue, Oct 27, 2020 at 03:14:14PM +1100, Stephen Rothwell wrote: > Hi all, > > After merging the vfs tree, today's linux-next build (sparc_defconfig) > failed like this: > > arch/sparc/lib/memset.S: Assembler messages: > arch/sparc/lib/memset.S:149: Error: Unknown opcode: `ext(12b, 13b,21f)' > > Caused by commit > > 0e0bbae08a6e ("sparc32: switch __bzero() away from range exception table > entries") > > merging badly with commit > > 7780918b3648 ("sparc32: fix a user-triggerable oops in clear_user()") > > from the sparc tree. > > The sparc tree commit above appears as commit > > 80537bbf19d6 ("sparc32: fix a user-triggerable oops in clear_user()") > > in the vfs tree as well. The patch adds one line which is later removed > by commit > > 0e0bbae08a6e ("sparc32: switch __bzero() away from range exception table > entries") > > in the vfs tree, but the git merge puts the line back again :-( > > I have added the following fix to the vfs tree merge I'll rebase that branch on top of sparc tree tomorrow (and eventually I'd like it to go through the sparc tree anyway).
[v2 07/11] arm64: dts: ls208xa: add DT node for external interrupt lines
From: Biwen Li Add device-tree node for external interrupt lines IRQ0-IRQ11. Signed-off-by: Biwen Li --- Change in v2: - none .../arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 33 ++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 41102dacc2e1..f75aa2ce4e2b 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -3,7 +3,7 @@ * Device Tree Include file for Freescale Layerscape-2080A family SoC. * * Copyright 2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * * Abhimanyu Saini * @@ -154,6 +154,37 @@ little-endian; }; + isc: syscon@1f7 { + compatible = "fsl,ls2080a-isc", "syscon"; + reg = <0x0 0x1f7 0x0 0x1>; + little-endian; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x1f7 0x1>; + + extirq: interrupt-controller@14 { + compatible = "fsl,ls2080a-extirq", "fsl,ls1088a-extirq"; + #interrupt-cells = <2>; + #address-cells = <0>; + interrupt-controller; + reg = <0x14 4>; + interrupt-map = + <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, + <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>, + <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, + <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x 0x0>; + }; + }; + tmu: tmu@1f8 { compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f8 0x0 0x1>; -- 2.17.1
[v2 08/11] arm64: dts: ls208xa-rdb: add interrupt line for RTC node
From: Biwen Li Add interrupt line for RTC node on ls208xa-rdb Signed-off-by: Biwen Li --- Change in v2: - none arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi index d0d670227ae2..4b71c4fcb35f 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi @@ -3,7 +3,7 @@ * Device Tree file for Freescale LS2080A RDB Board. * * Copyright 2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * * Abhimanyu Saini * @@ -56,6 +56,8 @@ rtc@68 { compatible = "dallas,ds3232"; reg = <0x68>; + /* IRQ_RTC_B -> IRQ06, active low */ + interrupts-extended = <&extirq 6 IRQ_TYPE_LEVEL_LOW>; }; }; -- 2.17.1
[v2 09/11] arm64: dts: lx2160a: add DT node for external interrupt lines
From: Biwen Li Add device-tree node for external interrupt lines IRQ0-IRQ11. Signed-off-by: Biwen Li --- Change in v2: - none .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 31 +++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi index d247e4228d60..095298a84f4e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi @@ -664,6 +664,37 @@ little-endian; }; + isc: syscon@1f7 { + compatible = "fsl,lx2160a-isc", "syscon"; + reg = <0x0 0x1f7 0x0 0x1>; + little-endian; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x1f7 0x1>; + + extirq: interrupt-controller@14 { + compatible = "fsl,lx2160a-extirq", "fsl,ls1088a-extirq"; + #interrupt-cells = <2>; + #address-cells = <0>; + interrupt-controller; + reg = <0x14 4>; + interrupt-map = + <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, + <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>, + <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, + <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x 0x0>; + }; + }; + tmu: tmu@1f8 { compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f8 0x0 0x1>; -- 2.17.1
[v2 11/11] dt-bindings: interrupt-controller: update bindings for supporting more SoCs
From: Biwen Li Update bindings for Layerscape external irqs, support more SoCs(LS1043A, LS1046A, LS1088A, LS208xA, LX216xA) Signed-off-by: Biwen Li --- Change in v2: - update reg property - update compatible property .../bindings/interrupt-controller/fsl,ls-extirq.txt| 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-extirq.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-extirq.txt index f0ad7801e8cf..0d635c24ef8b 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-extirq.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-extirq.txt @@ -1,6 +1,7 @@ * Freescale Layerscape external IRQs -Some Layerscape SOCs (LS1021A, LS1043A, LS1046A) support inverting +Some Layerscape SOCs (LS1021A, LS1043A, LS1046A +LS1088A, LS208xA, LX216xA) support inverting the polarity of certain external interrupt lines. The device node must be a child of the node representing the @@ -8,12 +9,17 @@ Supplemental Configuration Unit (SCFG). Required properties: - compatible: should be "fsl,-extirq", e.g. "fsl,ls1021a-extirq". + "fsl,ls1043a-extirq": for LS1043A, LS1046A. SCFG_INTPCR[31:0] of these SoCs + is stored/read as SCFG_INTPCR[0:31] defaultly(bit reverse). + "fsl,ls1088a-extirq": for LS1088A, LS208xA, LX216xA. + - #interrupt-cells: Must be 2. The first element is the index of the external interrupt line. The second element is the trigger type. - #address-cells: Must be 0. - interrupt-controller: Identifies the node as an interrupt controller - reg: Specifies the Interrupt Polarity Control Register (INTPCR) in - the SCFG. + the SCFG or the External Interrupt Control Register (IRQCR) in + the ISC. - interrupt-map: Specifies the mapping from external interrupts to GIC interrupts. - interrupt-map-mask: Must be <0x 0>. -- 2.17.1
[v2 10/11] arm64: dts: lx2160ardb: fix interrupt line for RTC node
From: Biwen Li Fix interrupt line for RTC node on lx2160ardb Signed-off-by: Biwen Li --- Change in v2: - none arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts index 54fe8cd3a711..f3bab76797fb 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts @@ -2,7 +2,7 @@ // // Device Tree file for LX2160ARDB // -// Copyright 2018 NXP +// Copyright 2018-2020 NXP /dts-v1/; @@ -151,8 +151,8 @@ rtc@51 { compatible = "nxp,pcf2129"; reg = <0x51>; - // IRQ10_B - interrupts = <0 150 0x4>; + /* IRQ_RTC_B -> IRQ08, active low */ + interrupts-extended = <&extirq 8 IRQ_TYPE_LEVEL_LOW>; }; }; -- 2.17.1
[v2 03/11] arm64: dts: ls1046a: add DT node for external interrupt lines
From: Biwen Li Add device-tree node for external interrupt lines IRQ0-IRQ11. Signed-off-by: Biwen Li --- Change in v2: - none .../arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 0246d975a206..dff3ee84c294 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -3,7 +3,7 @@ * Device Tree Include file for Freescale Layerscape-1046A family SoC. * * Copyright 2016 Freescale Semiconductor, Inc. - * Copyright 2018 NXP + * Copyright 2018-2020 NXP * * Mingkai Hu */ @@ -314,6 +314,31 @@ compatible = "fsl,ls1046a-scfg", "syscon"; reg = <0x0 0x157 0x0 0x1>; big-endian; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x157 0x1>; + + extirq: interrupt-controller@1ac { + compatible = "fsl,ls1046a-extirq", "fsl,ls1043a-extirq"; + #interrupt-cells = <2>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1ac 4>; + interrupt-map = + <0 0 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <1 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>, + <2 0 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, + <3 0 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, + <4 0 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <5 0 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, + <6 0 &gic GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, + <7 0 &gic GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, + <8 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, + <9 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, + <10 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>, + <11 0 &gic GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x 0x0>; + }; }; crypto: crypto@170 { -- 2.17.1
[v2 06/11] arm64: dts: ls1088ardb: fix interrupt line for RTC node
From: Biwen Li Fix interrupt line for RTC node on ls1088ardb Signed-off-by: Biwen Li --- Change in v2: - none arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 5633e59febc3..89c40d3f9a50 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -2,7 +2,7 @@ /* * Device Tree file for NXP LS1088A RDB Board. * - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * * Harninder Rai * @@ -51,8 +51,8 @@ rtc@51 { compatible = "nxp,pcf2129"; reg = <0x51>; - /* IRQ10_B */ - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + /* IRQ_RTC_B -> IRQ0_B(CPLD) -> IRQ00(CPU), active low */ + interrupts-extended = <&extirq 0 IRQ_TYPE_LEVEL_LOW>; }; }; }; -- 2.17.1
[v2 04/11] arm64: dts: ls1046ardb: Add interrupt line for RTC node
From: Hou Zhiqiang Add interrupt line for RTC node, which is low level active. Signed-off-by: Hou Zhiqiang --- Change in v2: - none arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts index d53ccc56bb63..60acdf0b689e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts @@ -3,6 +3,7 @@ * Device Tree Include file for Freescale Layerscape-1046A family SoC. * * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2019-2020 NXP * * Mingkai Hu */ @@ -74,6 +75,8 @@ rtc@51 { compatible = "nxp,pcf2129"; reg = <0x51>; + /* IRQ_RTC_B -> IRQ05, active low */ + interrupts-extended = <&extirq 5 IRQ_TYPE_LEVEL_LOW>; }; }; -- 2.17.1
[v2 05/11] arm64: dts: ls1088a: add DT node for external interrupt lines
From: Biwen Li Add device-tree node for external interrupt lines IRQ0-IRQ11. Signed-off-by: Biwen Li --- Change in v2: - none .../arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 33 ++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index 169f4742ae3b..12fe8f079c28 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -2,7 +2,7 @@ /* * Device Tree Include file for NXP Layerscape-1088A family SoC. * - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * * Harninder Rai * @@ -206,6 +206,37 @@ little-endian; }; + isc: syscon@1f7 { + compatible = "fsl,ls1088a-isc", "syscon"; + reg = <0x0 0x1f7 0x0 0x1>; + little-endian; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x1f7 0x1>; + + extirq: interrupt-controller@14 { + compatible = "fsl,ls1088a-extirq"; + #interrupt-cells = <2>; + #address-cells = <0>; + interrupt-controller; + reg = <0x14 4>; + interrupt-map = + <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, + <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>, + <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, + <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x 0x0>; + }; + }; + tmu: tmu@1f8 { compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f8 0x0 0x1>; -- 2.17.1
[v2 01/11] irqchip: ls-extirq: Add LS1043A, LS1088A external interrupt
From: Hou Zhiqiang Add an new IRQ chip declaration for LS1043A and LS1088A - compatible "fsl,ls1043a-extirq" for LS1043A, LS1046A. SCFG_INTPCR[31:0] of these SoCs is stored/read as SCFG_INTPCR[0:31] defaultly(bit reverse) - compatible "fsl,ls1088a-extirq" for LS1088A, LS208xA, LX216xA Signed-off-by: Hou Zhiqiang Signed-off-by: Biwen Li --- Change in v2: - add despcription of bit reverse - update copyright drivers/irqchip/irq-ls-extirq.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-ls-extirq.c b/drivers/irqchip/irq-ls-extirq.c index 4d1179fed77c..9587bc2607fc 100644 --- a/drivers/irqchip/irq-ls-extirq.c +++ b/drivers/irqchip/irq-ls-extirq.c @@ -1,5 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 - +/* + * Author: Rasmus Villemoes + * Copyright 2020 NXP + */ #define pr_fmt(fmt) "irq-ls-extirq: " fmt #include @@ -183,6 +186,9 @@ ls_extirq_of_init(struct device_node *node, struct device_node *parent) priv->bit_reverse = (revcr != 0); } + if (of_device_is_compatible(node, "fsl,ls1043a-extirq")) + priv->bit_reverse = true; + domain = irq_domain_add_hierarchy(parent_domain, 0, priv->nirq, node, &extirq_domain_ops, priv); if (!domain) @@ -195,3 +201,5 @@ ls_extirq_of_init(struct device_node *node, struct device_node *parent) } IRQCHIP_DECLARE(ls1021a_extirq, "fsl,ls1021a-extirq", ls_extirq_of_init); +IRQCHIP_DECLARE(ls1043a_extirq, "fsl,ls1043a-extirq", ls_extirq_of_init); +IRQCHIP_DECLARE(ls1088a_extirq, "fsl,ls1088a-extirq", ls_extirq_of_init); -- 2.17.1
[v2 02/11] arm64: dts: ls1043a: add DT node for external interrupt lines
From: Biwen Li Add device-tree node for external interrupt lines IRQ0-IRQ11. Signed-off-by: Biwen Li --- Change in v2: - none .../arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 5c2e370f6316..38a6d951ecc5 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -3,7 +3,7 @@ * Device Tree Include file for Freescale Layerscape-1043A family SoC. * * Copyright 2014-2015 Freescale Semiconductor, Inc. - * Copyright 2018 NXP + * Copyright 2018-2020 NXP * * Mingkai Hu */ @@ -311,6 +311,31 @@ compatible = "fsl,ls1043a-scfg", "syscon"; reg = <0x0 0x157 0x0 0x1>; big-endian; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x157 0x1>; + + extirq: interrupt-controller@1ac { + compatible = "fsl,ls1043a-extirq"; + #interrupt-cells = <2>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1ac 4>; + interrupt-map = + <0 0 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <1 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>, + <2 0 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, + <3 0 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, + <4 0 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <5 0 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, + <6 0 &gic GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, + <7 0 &gic GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, + <8 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, + <9 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, + <10 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>, + <11 0 &gic GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x 0x0>; + }; }; crypto: crypto@170 { -- 2.17.1
Re: [RFC] perf evlist: Warn if event group has mixed sw/hw events
Hi, On Tue, Oct 27, 2020 at 12:49 AM Alexander Shishkin wrote: > > Andi Kleen writes: > > > On Mon, Oct 26, 2020 at 11:19:37PM +0900, Namhyung Kim wrote: > >> This patch just added a warning before running it. I'd really want to > >> fix the kernel if possible but don't have a good idea. Thoughts? > > > > The easiest fix would be some multi threading in perf stat opening, then > > then > > extra latencies could be mostly hidden. One thread per group would probably > > be overkill, but just a few threads would lower the penalty significantly. > > > > I think that would be better than this patch and it's likely not that much > > more complicated, as this is already a lot of code. > > > >> +{ > >> +const char *known_sw_pmu[] = { > >> +"software", "tracepoint", "breakpoint", "kprobe", "uprobe", > >> "msr" > > > > That's a non scalable approach. New pmus get added regularly. It would be > > better to > > indicate this in a generic way from the kernel. > > That, and also, intel_pt is a software PMU and a few of its features > depend on intel_pt/.../ being a group leader. Thanks for the info, that's good to know. So do you mean intel_pt requires other HW events in the same group? Thanks Namhyung
Re: [RFC] perf evlist: Warn if event group has mixed sw/hw events
Hi Andi, On Tue, Oct 27, 2020 at 12:21 AM Andi Kleen wrote: > > On Mon, Oct 26, 2020 at 11:19:37PM +0900, Namhyung Kim wrote: > > This patch just added a warning before running it. I'd really want to > > fix the kernel if possible but don't have a good idea. Thoughts? > > The easiest fix would be some multi threading in perf stat opening, then then > extra latencies could be mostly hidden. One thread per group would probably > be overkill, but just a few threads would lower the penalty significantly. Thanks for the suggestion. Yeah we could use threads to circumvent the problem in userspace. But I think it'd better to solve it in the kernel. Another problem I see is when there's a concurrent perf event in the same context. Since it holds ctx->mutex during the synchronize_rcu the other event should wait for it too. It'd be nice if it can release the ctx->mutex before going to sleep unless we can remove it. > > I think that would be better than this patch and it's likely not that much > more complicated, as this is already a lot of code. > > > +{ > > + const char *known_sw_pmu[] = { > > + "software", "tracepoint", "breakpoint", "kprobe", "uprobe", > > "msr" > > That's a non scalable approach. New pmus get added regularly. It would be > better to > indicate this in a generic way from the kernel. Maybe we can add a new attribute (task_ctx?) for that. > > > + pr_warning("WARNING: Event group has mixed hw/sw > > events.\n" > > +"This will slow down the perf_event_open > > syscall.\n" > > +"Consider putting a hw event as a > > leader.\n\n"); > > You really need to tell the user which group, otherwise it is hard to find > in a large command line. OK Thanks Namhyung
Re: [PATCH 2/2] Makefile.extrawarn: limit -Wnested-externs to clang
On Mon, Oct 26, 2020 at 06:48:46PM -0700, Nathan Chancellor wrote: > On Mon, Oct 26, 2020 at 11:03:14PM +0100, Arnd Bergmann wrote: > > From: Arnd Bergmann > > > > The -Wnested-externs warning has become useless with gcc, since > > this warns every time that BUILD_BUG_ON() or similar macros > > are used. > > > > Signed-off-by: Arnd Bergmann > > Also see: > > 2486baae2cf6 ("objtool: Allow nested externs to enable BUILD_BUG()") > 6cf4ecf5c51d ("perf build: Allow nested externs to enable BUILD_BUG() usage") > > Reviewed-by: Nathan Chancellor Actually, just delete this line altogether. -Wnested-externs is a GCC only warning, the flag is only present in clang for compatibility with GCC: https://clang.llvm.org/docs/DiagnosticsReference.html#wnested-externs With that, my reviewed by still stands. Cheers, Nathan
Re: [PATCH v2 4/4] cpufreq: schedutil: Always call drvier if need_freq_update is set
Spelling mistake in $subject (driver) On 23-10-20, 17:36, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki > > Because sugov_update_next_freq() may skip a frequency update even if > the need_freq_update flag has been set for the policy at hand, policy > limits updates may not take effect as expected. > > For example, if the intel_pstate driver operates in the passive mode > with HWP enabled, it needs to update the HWP min and max limits when > the policy min and max limits change, respectively, but that may not > happen if the target frequency does not change along with the limit > at hand. In particular, if the policy min is changed first, causing > the target frequency to be adjusted to it, and the policy max limit > is changed later to the same value, the HWP max limit will not be > updated to follow it as expected, because the target frequency is > still equal to the policy min limit and it will not change until > that limit is updated. > > To address this issue, modify get_next_freq() to clear > need_freq_update only if the CPUFREQ_NEED_UPDATE_LIMITS flag is > not set for the cpufreq driver in use (and it should be set for all > potentially affected drivers) and make sugov_update_next_freq() > check need_freq_update and continue when it is set regardless of > whether or not the new target frequency is equal to the old one. > > Fixes: f6ebbcf08f37 ("cpufreq: intel_pstate: Implement passive mode with HWP > enabled") > Reported-by: Zhang Rui > Cc: 5.9+ # 5.9+ > Signed-off-by: Rafael J. Wysocki > --- > > New patch in v2. > > --- > kernel/sched/cpufreq_schedutil.c |8 ++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > Index: linux-pm/kernel/sched/cpufreq_schedutil.c > === > --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c > +++ linux-pm/kernel/sched/cpufreq_schedutil.c > @@ -102,11 +102,12 @@ static bool sugov_should_update_freq(str > static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time, > unsigned int next_freq) > { > - if (sg_policy->next_freq == next_freq) > + if (sg_policy->next_freq == next_freq && !sg_policy->need_freq_update) > return false; > > sg_policy->next_freq = next_freq; > sg_policy->last_freq_update_time = time; > + sg_policy->need_freq_update = false; > > return true; > } > @@ -164,7 +165,10 @@ static unsigned int get_next_freq(struct > if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update) > return sg_policy->next_freq; > > - sg_policy->need_freq_update = false; > + if (sg_policy->need_freq_update) > + sg_policy->need_freq_update = > + cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS); > + The behavior here is a bit different from what we did in cpufreq.c. In cpufreq core we are _always_ allowing the call to reach the driver's target() routine, but here we do it only if limits have changed. Wonder if we should have similar behavior here as well ? Over that the code here can be rewritten a bit like: if (sg_policy->need_freq_update) sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS); else if (freq == sg_policy->cached_raw_freq) return sg_policy->next_freq; -- viresh
[PATCH 0/1] drm/vc4: drv: Add error handding for bind
Hello all, There is a problem that if vc4_drm bind fails, a memory leak occurs on the drm_property_create side as shown below. Add error handding for drm_mode_config. unreferenced object 0xff80f5a7a6c8 (size 576): comm "swapper/0", pid 1, jiffies 4294892559 (age 181.448s) hex dump (first 32 bytes): 00 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 f8 f1 0e f5 80 ff ff ff e0 a6 a7 f5 80 ff ff ff backtrace: [] kmem_cache_alloc+0x1a4/0x328 [<9dfa1aab>] radix_tree_node_alloc.constprop.19+0x50/0x108 [ ] idr_get_free+0x21c/0x2b8 [<99f2eea6>] idr_alloc_u32+0x68/0xf0 [<525beb52>] idr_alloc+0x44/0x80 [ ] __drm_mode_object_add+0x64/0xc0 [<2c24dfc8>] drm_mode_object_add+0x3c/0x50 [ ] drm_property_create+0xf0/0x1a0 [<2e1a296b>] drm_connector_create_standard_properties+0x30/0x130 [<7c53e4bd>] drm_mode_config_init+0x138/0x498 [ ] vc4_drm_bind+0x168/0x1f8 [<41d69f98>] try_to_bring_up_master+0x180/0x1e8 [ ] component_master_add_with_match+0xbc/0x108 [<85cea46d>] vc4_platform_drm_probe+0xd8/0x108 [ ] platform_drv_probe+0x58/0xa8 [<3822d094>] really_probe+0x10c/0x350 Best regards, Hoegeun Hoegeun Kwon (1): drm/vc4: drv: Add error handding for bind drivers/gpu/drm/vc4/vc4_drv.c | 1 + 1 file changed, 1 insertion(+) -- 2.17.1
[PATCH 1/1] drm/vc4: drv: Add error handding for bind
There is a problem that if vc4_drm bind fails, a memory leak occurs on the drm_property_create side. Add error handding for drm_mode_config. Signed-off-by: Hoegeun Kwon --- drivers/gpu/drm/vc4/vc4_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index f1a5fd5dab6f..a17aa1db11b6 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -314,6 +314,7 @@ static int vc4_drm_bind(struct device *dev) component_unbind_all(dev, drm); gem_destroy: vc4_gem_destroy(drm); + drm_mode_config_cleanup(drm); vc4_bo_cache_destroy(drm); dev_put: drm_dev_put(drm); -- 2.17.1
linux-next: build failure after merge of the vfs tree
Hi all, After merging the vfs tree, today's linux-next build (sparc_defconfig) failed like this: arch/sparc/lib/memset.S: Assembler messages: arch/sparc/lib/memset.S:149: Error: Unknown opcode: `ext(12b, 13b,21f)' Caused by commit 0e0bbae08a6e ("sparc32: switch __bzero() away from range exception table entries") merging badly with commit 7780918b3648 ("sparc32: fix a user-triggerable oops in clear_user()") from the sparc tree. The sparc tree commit above appears as commit 80537bbf19d6 ("sparc32: fix a user-triggerable oops in clear_user()") in the vfs tree as well. The patch adds one line which is later removed by commit 0e0bbae08a6e ("sparc32: switch __bzero() away from range exception table entries") in the vfs tree, but the git merge puts the line back again :-( I have added the following fix to the vfs tree merge From: Stephen Rothwell Date: Tue, 27 Oct 2020 15:05:28 +1100 Subject: [PATCH] fix up for merge of arch/sparc/lib/memset.S Signed-off-by: Stephen Rothwell --- arch/sparc/lib/memset.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S index 522f45a952a0..eaff68213fdf 100644 --- a/arch/sparc/lib/memset.S +++ b/arch/sparc/lib/memset.S @@ -146,7 +146,6 @@ __bzero: ZERO_LAST_BLOCKS(%o0, 0x48, %g2) ZERO_LAST_BLOCKS(%o0, 0x08, %g2) 13: - EXT(12b, 13b, 21f) be 8f andcc %o1, 4, %g0 -- 2.28.0 -- Cheers, Stephen Rothwell pgp9n65n8RG92.pgp Description: OpenPGP digital signature
Re: [PATCH v2 1/1] KVM: arm64: Correctly handle the mmio faulting
Hi Santosh, On 10/26/20 10:24 PM, Santosh Shukla wrote: The Commit:6d674e28 introduces a notion to detect and handle the device mapping. The commit checks for the VM_PFNMAP flag is set in vma->flags and if set then marks force_pte to true such that if force_pte is true then ignore the THP function check (/transparent_hugepage_adjust()). There could be an issue with the VM_PFNMAP flag setting and checking. For example consider a case where the mdev vendor driver register's the vma_fault handler named vma_mmio_fault(), which maps the host MMIO region in-turn calls remap_pfn_range() and maps the MMIO's vma space. Where, remap_pfn_range implicitly sets the VM_PFNMAP flag into vma->flags. Now lets assume a mmio fault handing flow where guest first access the MMIO region whose 2nd stage translation is not present. So that results to arm64-kvm hypervisor executing guest abort handler, like below: kvm_handle_guest_abort() --> user_mem_abort()--> { ... 0. checks the vma->flags for the VM_PFNMAP. 1. Since VM_PFNMAP flag is not yet set so force_pte _is_ false; 2. gfn_to_pfn_prot() --> __gfn_to_pfn_memslot() --> fixup_user_fault() --> handle_mm_fault()--> __do_fault() --> vma_mmio_fault() --> // vendor's mdev fault handler remap_pfn_range()--> // Here sets the VM_PFNMAP flag into vma->flags. 3. Now that force_pte is set to false in step-2), will execute transparent_hugepage_adjust() func and that lead to Oops [4]. } The proposition is to set force_pte=true if kvm_is_device_pfn is true. [4] THP Oops: pc: kvm_is_transparent_hugepage+0x18/0xb0 ... ... user_mem_abort+0x340/0x9b8 kvm_handle_guest_abort+0x248/0x468 handle_exit+0x150/0x1b0 kvm_arch_vcpu_ioctl_run+0x4d4/0x778 kvm_vcpu_ioctl+0x3c0/0x858 ksys_ioctl+0x84/0xb8 __arm64_sys_ioctl+0x28/0x38 Tested on Huawei Kunpeng Taishan-200 arm64 server, Using VFIO-mdev device. Linux-5.10-rc1 tip: 3650b228 Fixes: 6d674e28 ("KVM: arm/arm64: Properly handle faulting of device mappings") Suggested-by: Marc Zyngier Signed-off-by: Santosh Shukla --- v2: - Per Marc's suggestion - setting force_pte=true. - Rebased and tested for 5.10-rc1 commit: 3650b228 v1: https://lkml.org/lkml/2020/10/21/460 arch/arm64/kvm/mmu.c | 1 + 1 file changed, 1 insertion(+) Reviewed-by: Gavin Shan diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 19aacc7..d4cd253 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -839,6 +839,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (kvm_is_device_pfn(pfn)) { device = true; + force_pte = true; } else if (logging_active && !write_fault) { /* * Only actually map the page as writable if this was a write Cheers, Gavin
Re: [PATCH net-next 01/11] atm: horizon: shut up clang null pointer arithmetic warning
On Mon, Oct 26, 2020 at 8:56 PM Xie He wrote: > > > - for (mem = (HDW *) memmap; mem < (HDW *) (memmap + 1); ++mem) > > + for (mem = (HDW *) memmap; mem < (HDW *) ((uintptr_t)memmap + 1); ++mem) > > Note that these two lines are semantically different. In the first line, > "+ 1" moves the pointer by (sizeof memmap) bytes. However in the second > line, "+ 1" moves the pointer by only 1 byte. Correction: in the first line "+ 1" moves the pointer by (sizeof *memmap) bytes.
RE: [PATCH v3] usb: cdns3: Variable 'length' set but not used
> > > > A gentle ping. > > > > I assume that you should add this and the rest overdue cdsn3 patches > > as first to you ci-for-usb-next branch. > > Am I right? > > > > Hi Pawel, > > I queued them locally, and I waited for v5.10-rc1 which was out yesterday, > then > I will apply them, and add cdns3 patches to my kernel.org branch. Will update > you these two days. > > Peter Hi Pawel, The cdns3 -next patches pushed to: for-usb-next; cdns3 -fixes patches pushed to: for-usb-fixes. The git is: git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git Currently, I only pushed three of your patches, would you please review my patches, thanks. Peter
Re: [PATCH net-next 01/11] atm: horizon: shut up clang null pointer arithmetic warning
> - for (mem = (HDW *) memmap; mem < (HDW *) (memmap + 1); ++mem) > + for (mem = (HDW *) memmap; mem < (HDW *) ((uintptr_t)memmap + 1); ++mem) Note that these two lines are semantically different. In the first line, "+ 1" moves the pointer by (sizeof memmap) bytes. However in the second line, "+ 1" moves the pointer by only 1 byte. This driver is old, but let's still keep its code correct!
Re: [PATCH v3 01/56] scripts: kernel-doc: fix typedef parsing
On Mon, 2020-10-26 at 08:03 +0100, Mauro Carvalho Chehab wrote: [] > Well, this can help: > my $typedef_type = qr { ((?:\w+\s+){1,}) }x; unbounded captures are generally bad, I suggest a limit like {1,5} > if ($x =~ /typedef\s+((?:\w+\s+){1,})\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ || > $x =~ /typedef\s+((?:\w+\s+){1,})\s*\*?(\w\S+)\s*\s*\((.*)\);/) { [] > Fix the regex in order to accept composite types when > defining a typedef for a function pointer. [] > diff --git a/scripts/kernel-doc b/scripts/kernel-doc [] > @@ -1438,13 +1438,14 @@ sub dump_typedef($$) { > $x =~ s@/\*.*?\*/@@gos; # strip comments. > > > # Parse function prototypes > -if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ || > - $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) { > +if ($x =~ /typedef\s+((?:\w+\s+){1,})\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ || > + $x =~ /typedef\s+((?:\w+\s+){1,})\s*\*?(\w\S+)\s*\s*\((.*)\);/) { This typedef does not allow * returns like const unsigned char *(*string)(args...); or unsigned char *const(*fn)(args...); or void *(*alloc)(args...); (not to mention the truly unusual stuff like the typedefs in tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c) typedef void (* (*signal_t)(int, void (*)(int)))(int); typedef char * (*fn_ptr_arr1_t[10])(int **); typedef char * (* const (* const fn_ptr_arr2_t[5])())(char * (*)(int));
Re: [PATCH v1] Input: ads7846: do not overwrite spi->mode flags set by spi framework
On Thu, Oct 22, 2020 at 08:54:02AM +0200, Oleksij Rempel wrote: > On Wed, Oct 21, 2020 at 11:27:57AM -0700, Dmitry Torokhov wrote: > > On Wed, Oct 21, 2020 at 12:56:14PM +0200, Oleksij Rempel wrote: > > > > > > As you can see, I would need to configure my dts with spi-cs-high flag, > > > even if the hardware is actually ACTIVE_LOW. If I will go this way, I > > > would risk a regression as soon as this issue is fixed. > > > > > > Since the spi framework is already parsing devicetree and set all needed > > > flags, I assume it is wrong to blindly drop all this flags in the > > > driver. > > > > Yes, but I wonder if the devices can only work in mode 0 we should be > > doing: > > > > spi->mode &= ~SPI_MODE_MASK; // to be defined as 0x03 in spi.h > > spi->mode |= SPI_MODE_0; > > > > as we can't simply "or" mode value as is > > Why not? This values are taken from device tree. If some developer > decided to add them, then driver should take it over. Even if this > values will break the functionality. > > Other properties of this driver will break the functionality too of this > driver too, so why should we silently filter only set of this bits? What I was trying to say is that if driver wants to set mode to particular value it should not "or" the value, as it will not reset the relevant bits. I.e. if there some undesirable data in spi->mode mode bits it will not get set properly by essentially doing "spi->mode |= 0". That is why I said the driver needs to clear mode bits and set them to the desired mode. Thanks. -- Dmitry
Re: [PATCH v1] Input: touchscreen: ads7846.c: Fix race that causes missing releases
Hi Oleksij, On Mon, Oct 26, 2020 at 02:21:17PM +0100, Oleksij Rempel wrote: > From: David Jander > > If touchscreen is released while busy reading HWMON device, the release > can be missed. The IRQ thread is not started because no touch is active > and BTN_TOUCH release event is never sent. > > Fixes: f5a28a7d4858f94a ("Input: ads7846 - avoid pen up/down when reading > hwmon") > Co-Developed-by: David Jander > Signed-off-by: David Jander > Signed-off-by: Oleksij Rempel > --- > drivers/input/touchscreen/ads7846.c | 16 > 1 file changed, 16 insertions(+) > > diff --git a/drivers/input/touchscreen/ads7846.c > b/drivers/input/touchscreen/ads7846.c > index ea31956f3a90..0236a119c52d 100644 > --- a/drivers/input/touchscreen/ads7846.c > +++ b/drivers/input/touchscreen/ads7846.c > @@ -211,10 +211,26 @@ static void ads7846_stop(struct ads7846 *ts) > } > } > > +static int get_pendown_state(struct ads7846 *ts); Not a fan forward declarations, just move the definition if needed. > + > /* Must be called with ts->lock held */ > static void ads7846_restart(struct ads7846 *ts) > { > + unsigned int pdstate; I do not see it being used. Do you have more patches for the driver? > + > if (!ts->disabled && !ts->suspended) { > + /* Check if pen was released since last stop */ > + if (ts->pendown && !get_pendown_state(ts)) { > + struct input_dev *input = ts->input; > + > + input_report_key(input, BTN_TOUCH, 0); > + input_report_abs(input, ABS_PRESSURE, 0); > + input_sync(input); > + > + ts->pendown = false; > + dev_vdbg(&ts->spi->dev, "UP\n"); I wonder if we should not have ads7846_report_pen_up(struct ads7846 *ts) > + } > + > /* Tell IRQ thread that it may poll the device. */ > ts->stopped = false; > mb(); > -- > 2.28.0 > Thanks. -- Dmitry
Re: [PATCH v3 5/6] dt-bindings: spi: Convert cadence-quadspi.txt to cadence-quadspi.yaml
Hi Rob, Thank you very much for the review comments... On 26/10/2020 9:08 pm, Rob Herring wrote: On Mon, Oct 26, 2020 at 05:45:18PM +0800, Ramuthevar,Vadivel MuruganX wrote: From: Ramuthevar Vadivel Murugan Convert the cadence-quadspi.txt documentation to cadence-quadspi.yaml remove the cadence-quadspi.txt from Documentation/devicetree/bindings/spi/ Signed-off-by: Ramuthevar Vadivel Murugan --- .../devicetree/bindings/spi/cadence-quadspi.txt| 67 -- .../devicetree/bindings/spi/cadence-quadspi.yaml | 148 + 2 files changed, 148 insertions(+), 67 deletions(-) delete mode 100644 Documentation/devicetree/bindings/spi/cadence-quadspi.txt create mode 100644 Documentation/devicetree/bindings/spi/cadence-quadspi.yaml diff --git a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt deleted file mode 100644 index 945be7d5b236.. --- a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt +++ /dev/null @@ -1,67 +0,0 @@ -* Cadence Quad SPI controller - -Required properties: -- compatible : should be one of the following: - Generic default - "cdns,qspi-nor". - For TI 66AK2G SoC - "ti,k2g-qspi", "cdns,qspi-nor". - For TI AM654 SoC - "ti,am654-ospi", "cdns,qspi-nor". -- reg : Contains two entries, each of which is a tuple consisting of a - physical address and length. The first entry is the address and - length of the controller register set. The second entry is the - address and length of the QSPI Controller data area. -- interrupts : Unit interrupt specifier for the controller interrupt. -- clocks : phandle to the Quad SPI clock. -- cdns,fifo-depth : Size of the data FIFO in words. -- cdns,fifo-width : Bus width of the data FIFO in bytes. -- cdns,trigger-address : 32-bit indirect AHB trigger address. - -Optional properties: -- cdns,is-decoded-cs : Flag to indicate whether decoder is used or not. -- cdns,rclk-en : Flag to indicate that QSPI return clock is used to latch - the read data rather than the QSPI clock. Make sure that QSPI return - clock is populated on the board before using this property. - -Optional subnodes: -Subnodes of the Cadence Quad SPI controller are spi slave nodes with additional -custom properties: -- cdns,read-delay : Delay for read capture logic, in clock cycles -- cdns,tshsl-ns : Delay in nanoseconds for the length that the master - mode chip select outputs are de-asserted between - transactions. -- cdns,tsd2d-ns : Delay in nanoseconds between one chip select being - de-activated and the activation of another. -- cdns,tchsh-ns : Delay in nanoseconds between last bit of current - transaction and deasserting the device chip select - (qspi_n_ss_out). -- cdns,tslch-ns : Delay in nanoseconds between setting qspi_n_ss_out low - and first bit transfer. -- resets : Must contain an entry for each entry in reset-names. - See ../reset/reset.txt for details. -- reset-names : Must include either "qspi" and/or "qspi-ocp". - -Example: - - qspi: spi@ff705000 { - compatible = "cdns,qspi-nor"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xff705000 0x1000>, - <0xffa0 0x1000>; - interrupts = <0 151 4>; - clocks = <&qspi_clk>; - cdns,is-decoded-cs; - cdns,fifo-depth = <128>; - cdns,fifo-width = <4>; - cdns,trigger-address = <0x>; - resets = <&rst QSPI_RESET>, <&rst QSPI_OCP_RESET>; - reset-names = "qspi", "qspi-ocp"; - - flash0: n25q00@0 { - ... - cdns,read-delay = <4>; - cdns,tshsl-ns = <50>; - cdns,tsd2d-ns = <50>; - cdns,tchsh-ns = <4>; - cdns,tslch-ns = <4>; - }; - }; diff --git a/Documentation/devicetree/bindings/spi/cadence-quadspi.yaml b/Documentation/devicetree/bindings/spi/cadence-quadspi.yaml new file mode 100644 index ..b1b3d3ce0cc2 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/cadence-quadspi.yaml @@ -0,0 +1,148 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/cadence-quadspi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cadence Quad SPI controller + +maintainers: + - Vadivel Murugan + +allOf: + - $ref: "spi-controller.yaml#" + +properties: + compatible: +oneOf: + - items: + - const: cdns,qspi-nor + - const: ti,k2g-qspi, cdns,qspi-nor + - const: ti,am654-ospi, cdns,qspi-nor + + reg: +items: + - description: the controller register set + - description: the controller data a
Re:Re: [PATCH] sched/rt.c: use list_is_singular() instead of '->prev != ->next'
>Perhaps there should be a list_has_more_than_one() API, as list_is_singular >requires two checks, and the "more_than_one" only requires a single check. > >list_is_singular() is: > > return !list_empty(list) && (list->next == list->prev); > > >which is more work than what you are replacing. > Hi, Steve: Thanks for your explanation. Maybe we should add another api called "list_more_than_one" just without list_empty() check. I will send PATCH V2 later. Thank.
[PATCH v2 2/2] scsi: arcmsr: Confirm getting a free ccb is in spin_lock circle
From: ching Huang Confirm getting a free ccb is in spin_lock circle. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 7cfae1d..127fe50 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3162,10 +3162,12 @@ message_out: static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock *acb) { - struct list_head *head = &acb->ccb_free_list; + struct list_head *head; struct CommandControlBlock *ccb = NULL; unsigned long flags; + spin_lock_irqsave(&acb->ccblist_lock, flags); + head = &acb->ccb_free_list; if (!list_empty(head)) { ccb = list_entry(head->next, struct CommandControlBlock, list); list_del_init(&ccb->list);
Re: [PATCH v4 1/5] scsi: ufs: atomic update for clkgating_enable
On 2020-10-27 11:33, Jaegeuk Kim wrote: On 10/27, Can Guo wrote: On 2020-10-27 03:51, Jaegeuk Kim wrote: > From: Jaegeuk Kim > > When giving a stress test which enables/disables clkgating, we hit > device > timeout sometimes. This patch avoids subtle racy condition to address > it. > > Note that, this requires a patch to address the device stuck by > REQ_CLKS_OFF in > __ufshcd_release(). > > The fix is "scsi: ufs: avoid to call REQ_CLKS_OFF to CLKS_OFF". Why don't you just squash the fix into this one? I'm seeing this patch just revealed that problem. That scenario (back to back calling of ufshcd_release()) only happens when you stress the clkgate_enable sysfs node, so let's keep the fix as one to make things simple. What do you think? Thanks, Can Guo. Thanks, Can Guo. > > Signed-off-by: Jaegeuk Kim > --- > drivers/scsi/ufs/ufshcd.c | 12 ++-- > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index cc8d5f0c3fdc..6c9269bffcbd 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -1808,19 +1808,19 @@ static ssize_t > ufshcd_clkgate_enable_store(struct device *dev, >return -EINVAL; > >value = !!value; > + > + spin_lock_irqsave(hba->host->host_lock, flags); >if (value == hba->clk_gating.is_enabled) >goto out; > > - if (value) { > - ufshcd_release(hba); > - } else { > - spin_lock_irqsave(hba->host->host_lock, flags); > + if (value) > + __ufshcd_release(hba); > + else >hba->clk_gating.active_reqs++; > - spin_unlock_irqrestore(hba->host->host_lock, flags); > - } > >hba->clk_gating.is_enabled = value; > out: > + spin_unlock_irqrestore(hba->host->host_lock, flags); >return count; > }
Re: [PATCH v4 1/5] scsi: ufs: atomic update for clkgating_enable
On 10/27, Can Guo wrote: > On 2020-10-27 03:51, Jaegeuk Kim wrote: > > From: Jaegeuk Kim > > > > When giving a stress test which enables/disables clkgating, we hit > > device > > timeout sometimes. This patch avoids subtle racy condition to address > > it. > > > > Note that, this requires a patch to address the device stuck by > > REQ_CLKS_OFF in > > __ufshcd_release(). > > > > The fix is "scsi: ufs: avoid to call REQ_CLKS_OFF to CLKS_OFF". > > Why don't you just squash the fix into this one? I'm seeing this patch just revealed that problem. > > Thanks, > > Can Guo. > > > > > Signed-off-by: Jaegeuk Kim > > --- > > drivers/scsi/ufs/ufshcd.c | 12 ++-- > > 1 file changed, 6 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > > index cc8d5f0c3fdc..6c9269bffcbd 100644 > > --- a/drivers/scsi/ufs/ufshcd.c > > +++ b/drivers/scsi/ufs/ufshcd.c > > @@ -1808,19 +1808,19 @@ static ssize_t > > ufshcd_clkgate_enable_store(struct device *dev, > > return -EINVAL; > > > > value = !!value; > > + > > + spin_lock_irqsave(hba->host->host_lock, flags); > > if (value == hba->clk_gating.is_enabled) > > goto out; > > > > - if (value) { > > - ufshcd_release(hba); > > - } else { > > - spin_lock_irqsave(hba->host->host_lock, flags); > > + if (value) > > + __ufshcd_release(hba); > > + else > > hba->clk_gating.active_reqs++; > > - spin_unlock_irqrestore(hba->host->host_lock, flags); > > - } > > > > hba->clk_gating.is_enabled = value; > > out: > > + spin_unlock_irqrestore(hba->host->host_lock, flags); > > return count; > > }
[PATCH v2] sched: sched_domain fix highest_flag_domain function
the highest_flag_domain is to search the highest sched_domain containing flag, but if the lower sched_domain didn't contain the flag, but the higher sched_domain contains the flag, the function will return NULL instead of the higher sched_domain. For example: In MC domain : no SD_ASYM_CPUCAPACITY flag; In DIE domain : containing SD_ASYM_CPUCAPACITY flag; the "highest_flag_domain(cpu, SD_ASYM_CPUCAPACITY)" will return NULL. Signed-off-by: Xuewen Yan --- kernel/sched/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 28709f6..2c7c566 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1427,7 +1427,7 @@ static inline struct sched_domain *highest_flag_domain(int cpu, int flag) for_each_domain(cpu, sd) { if (!(sd->flags & flag)) - break; + continue; hsd = sd; } -- 1.9.1
Re: [RFC PATCH 1/6] docs: networking: add the document for DFL Ether Group driver
On Mon, Oct 26, 2020 at 08:14:00PM +0100, Andrew Lunn wrote: > > > > > Do you really mean PHY? I actually expect it is PCS? > > > > > > > > For this implementation, yes. > > > > > > Yes, you have a PHY? Or Yes, it is PCS? > > > > Sorry, I mean I have a PHY. > > > > > > > > To me, the phylib maintainer, having a PHY means you have a base-T > > > interface, 25Gbase-T, 40Gbase-T? That would be an odd and expensive > > > architecture when you should be able to just connect SERDES interfaces > > > together. > > You really have 25Gbase-T, 40Gbase-T? Between the FPGA & XL710? > What copper PHYs are using? Sorry for the confusing. I'll check with our board designer and reply later. > > > I see your concerns about the SERDES interface between FPGA & XL710. > > I have no concerns about direct SERDES connections. That is the normal > way of doing this. It keeps it a lot simpler, since you don't have to > worry about driving the PHYs. > > > I did some investigation about the DSA, and actually I wrote a > > experimental DSA driver. It works and almost meets my need, I can make > > configuration, run pktgen on slave inf. > > Cool. As i said, I don't know if this actually needs to be a DSA > driver. It might just need to borrow some ideas from DSA. > > > Mm.. seems the hardware should be changed, either let host directly > > access the QSFP, or re-design the BMC to provide more info for QSFP. > > At a minimum, you need to support ethtool -m. It could be a firmware > call to the BMC, our you expose the i2c bus somehow. There are plenty > of MAC drivers which implement eththool -m without using phylink. > > But i think you need to take a step back first, and look at the bigger > picture. What is Intel's goal? Are they just going to sell complete > cards? Or do they also want to sell the FPGA as a components anybody > get put onto their own board? > > If there are only ever going to be compete cards, then you can go the > firmware direction, push a lot of functionality into the BMC, and have > the card driver make firmware calls to control the SFP, retimer, > etc. You can then throw away your mdio and phy driver hacks. > > If however, the FPGA is going to be available as a component, can you > also assume there is a BMC? Running Intel firmware? Can the customer > also modify this firmware for their own needs? I think that is going > to be difficult. So you need to push as much as possible towards > linux, and let Linux drive all the hardware, the SFP, retimer, FPGA, > etc. This is a very helpful. I'll share with our team and reconsider about the design. Thanks, Yilun > > Andrew >
[PATCH v2 1/2] scsi: arcmsr: configure the default SCSI device command timeout value
From: ching Huang Configure the default SCSI device command timeout value. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 5d054d5..0f6abd2 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -83,6 +83,7 @@ struct device_attribute; #define PCI_DEVICE_ID_ARECA_1886 0x188A #defineARCMSR_HOURS(1000 * 60 * 60 * 4) #defineARCMSR_MINUTES (1000 * 60 * 60) +#define ARCMSR_DEFAULT_TIMEOUT 90 /* ** ** diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index e4fdb47..7cfae1d 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -99,6 +99,10 @@ static int set_date_time = 0; module_param(set_date_time, int, S_IRUGO); MODULE_PARM_DESC(set_date_time, " send date, time to iop(0 ~ 1), set_date_time=1(enable), default(=0) is disable"); +static int cmd_timeout = ARCMSR_DEFAULT_TIMEOUT; +module_param(cmd_timeout, int, S_IRUGO); +MODULE_PARM_DESC(cmd_timeout, " scsi cmd timeout(0 ~ 120 sec.), default is 90"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12 @@ -140,6 +144,7 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *); static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb); static void arcmsr_set_iop_datetime(struct timer_list *); +static int arcmsr_slave_config(struct scsi_device *sdev); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -155,6 +160,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .eh_abort_handler = arcmsr_abort, .eh_bus_reset_handler = arcmsr_bus_reset, .bios_param = arcmsr_bios_param, + .slave_configure= arcmsr_slave_config, .change_queue_depth = arcmsr_adjust_disk_queue_depth, .can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD, .this_id= ARCMSR_SCSI_INITIATOR_ID, @@ -3256,6 +3262,16 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(arcmsr_queue_command) +static int arcmsr_slave_config(struct scsi_device *sdev) +{ + unsigned intdev_timeout; + + dev_timeout = sdev->request_queue->rq_timeout; + if ((cmd_timeout > 0) && ((cmd_timeout * HZ) > dev_timeout)) + blk_queue_rq_timeout(sdev->request_queue, cmd_timeout * HZ); + return 0; +} + static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t *rwbuffer) { int count;