[PATCH v4 8/8] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers
EASRC (Enhanced Asynchronous Sample Rate Converter) is a new IP module found on i.MX8MN. It is different with old ASRC module. The primary features for the EASRC are as follows: - 4 Contexts - groups of channels with an independent time base - Fully independent and concurrent context control - Simultaneous processing of up to 32 audio channels - Programmable filter charachteristics for each context - 32, 24, 20, and 16-bit fixed point audio sample support - 32-bit floating point audio sample support - 8kHz to 384kHz sample rate - 1/16 to 8x sample rate conversion ratio Signed-off-by: Shengjiu Wang Signed-off-by: Cosmin-Gabriel Samoila --- sound/soc/fsl/Kconfig | 11 + sound/soc/fsl/Makefile|2 + sound/soc/fsl/fsl_easrc.c | 2111 + sound/soc/fsl/fsl_easrc.h | 651 4 files changed, 2775 insertions(+) create mode 100644 sound/soc/fsl/fsl_easrc.c create mode 100644 sound/soc/fsl/fsl_easrc.h diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 65e8cd4be930..ea7b4787a8af 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -84,6 +84,17 @@ config SND_SOC_FSL_MICFIL Say Y if you want to add Pulse Density Modulation microphone interface (MICFIL) support for NXP. +config SND_SOC_FSL_EASRC + tristate "Enhanced Asynchronous Sample Rate Converter (EASRC) module support" + depends on SND_SOC_FSL_ASRC + select REGMAP_MMIO + select SND_SOC_GENERIC_DMAENGINE_PCM + help + Say Y if you want to add Enhanced ASRC support for NXP. The ASRC is + a digital module that converts audio from a source sample rate to a + destination sample rate. It is a new design module compare with the + old ASRC. + config SND_SOC_FSL_UTILS tristate diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 8cde88c72d93..b835eebf8825 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -24,6 +24,7 @@ snd-soc-fsl-micfil-objs := fsl_micfil.o snd-soc-fsl-utils-objs := fsl_utils.o snd-soc-fsl-dma-objs := fsl_dma.o snd-soc-fsl-mqs-objs := fsl_mqs.o +snd-soc-fsl-easrc-objs := fsl_easrc.o obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o @@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o +obj-$(CONFIG_SND_SOC_FSL_EASRC) += snd-soc-fsl-easrc.o obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o # MPC5200 Platform Support diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c new file mode 100644 index ..52c76760de0e --- /dev/null +++ b/sound/soc/fsl/fsl_easrc.c @@ -0,0 +1,2111 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright 2019 NXP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_easrc.h" +#include "imx-pcm.h" + +#define FSL_EASRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ +SNDRV_PCM_FMTBIT_U16_LE | \ +SNDRV_PCM_FMTBIT_S24_LE | \ +SNDRV_PCM_FMTBIT_S24_3LE | \ +SNDRV_PCM_FMTBIT_U24_LE | \ +SNDRV_PCM_FMTBIT_U24_3LE | \ +SNDRV_PCM_FMTBIT_S32_LE | \ +SNDRV_PCM_FMTBIT_U32_LE | \ +SNDRV_PCM_FMTBIT_S20_3LE | \ +SNDRV_PCM_FMTBIT_U20_3LE | \ +SNDRV_PCM_FMTBIT_FLOAT_LE) + +static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct fsl_asrc *easrc = snd_soc_component_get_drvdata(comp); + struct fsl_easrc_priv *easrc_priv = easrc->private; + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regval = ucontrol->value.integer.value[0]; + + easrc_priv->bps_iec958[mc->regbase] = regval; + + return 0; +} + +static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct fsl_asrc *easrc = snd_soc_component_get_drvdata(comp); + struct fsl_easrc_priv *easrc_priv = easrc->private; + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_va
[PATCH v4 6/8] ASoC: fsl_asrc: Move common definition to fsl_asrc_common
There is a new ASRC included in i.MX serial platform, there are some common definition can be shared with each other. So move the common definition to a separate header file. And add fsl_asrc_pair_priv and fsl_asrc_priv for the variable specific for the module, which can be used internally. Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_asrc.c| 81 +++- sound/soc/fsl/fsl_asrc.h| 74 ++ sound/soc/fsl/fsl_asrc_common.h | 105 sound/soc/fsl/fsl_asrc_dma.c| 25 4 files changed, 176 insertions(+), 109 deletions(-) create mode 100644 sound/soc/fsl/fsl_asrc_common.h diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 1ae4b863eadd..2c63349d07ea 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -308,8 +308,10 @@ static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair, */ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) { - struct asrc_config *config = pair->config; + struct fsl_asrc_pair_priv *pair_priv = pair->private; + struct asrc_config *config = pair_priv->config; struct fsl_asrc *asrc = pair->asrc; + struct fsl_asrc_priv *asrc_priv = asrc->private; enum asrc_pair_index index = pair->index; enum asrc_word_width input_word_width; enum asrc_word_width output_word_width; @@ -392,11 +394,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) } /* Validate input and output clock sources */ - clk_index[IN] = asrc->clk_map[IN][config->inclk]; - clk_index[OUT] = asrc->clk_map[OUT][config->outclk]; + clk_index[IN] = asrc_priv->clk_map[IN][config->inclk]; + clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk]; /* We only have output clock for ideal ratio mode */ - clk = asrc->asrck_clk[clk_index[ideal ? OUT : IN]]; + clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]]; clk_rate = clk_get_rate(clk); rem[IN] = do_div(clk_rate, inrate); @@ -417,7 +419,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) div[IN] = min_t(u32, 1024, div[IN]); - clk = asrc->asrck_clk[clk_index[OUT]]; + clk = asrc_priv->asrck_clk[clk_index[OUT]]; clk_rate = clk_get_rate(clk); if (ideal && use_ideal_rate) rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE); @@ -437,13 +439,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) /* Set the channel number */ channels = config->channel_num; - if (asrc->soc->channel_bits < 4) + if (asrc_priv->soc->channel_bits < 4) channels /= 2; /* Update channels for current pair */ regmap_update_bits(asrc->regmap, REG_ASRCNCR, - ASRCNCR_ANCi_MASK(index, asrc->soc->channel_bits), - ASRCNCR_ANCi(index, channels, asrc->soc->channel_bits)); + ASRCNCR_ANCi_MASK(index, asrc_priv->soc->channel_bits), + ASRCNCR_ANCi(index, channels, asrc_priv->soc->channel_bits)); /* Default setting: Automatic selection for processing mode */ regmap_update_bits(asrc->regmap, REG_ASRCTR, @@ -568,9 +570,10 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); + struct fsl_asrc_priv *asrc_priv = asrc->private; /* Odd channel number is not valid for older ASRC (channel_bits==3) */ - if (asrc->soc->channel_bits == 3) + if (asrc_priv->soc->channel_bits == 3) snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); @@ -586,6 +589,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_asrc_pair *pair = runtime->private_data; + struct fsl_asrc_pair_priv *pair_priv = pair->private; unsigned int channels = params_channels(params); unsigned int rate = params_rate(params); struct asrc_config config; @@ -597,7 +601,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, return ret; } - pair->config = &config; + pair_priv->config = &config; config.pair = pair->index; config.channel_num = channels; @@ -931,10 +935,16 @@ static irqreturn_t fsl_asrc_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index) +{ + return REG_ASRDx(dir, index); +} + static int fsl_asrc_probe(struct platform_devi
[PATCH v4 7/8] ASoC: dt-bindings: fsl_easrc: Add document for EASRC
EASRC (Enhanced Asynchronous Sample Rate Converter) is a new IP module found on i.MX8MN. Signed-off-by: Shengjiu Wang --- .../devicetree/bindings/sound/fsl,easrc.yaml | 96 +++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.yaml diff --git a/Documentation/devicetree/bindings/sound/fsl,easrc.yaml b/Documentation/devicetree/bindings/sound/fsl,easrc.yaml new file mode 100644 index ..500af8f0c8f0 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,easrc.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/fsl,easrc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP Asynchronous Sample Rate Converter (ASRC) Controller + +maintainers: + - Shengjiu Wang + +properties: + $nodename: +pattern: "^easrc@.*" + + compatible: +oneOf: + - items: +- enum: + - fsl,imx8mn-easrc + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + clocks: +items: + - description: Peripheral clock + + clock-names: +items: + - const: mem + + dmas: +maxItems: 8 + + dma-names: +oneOf: + - items: + - const: ctx0_rx + - const: ctx0_tx + - const: ctx1_rx + - const: ctx1_tx + - const: ctx2_rx + - const: ctx2_tx + - const: ctx3_rx + - const: ctx3_tx + + fsl,easrc-ram-script-name: +$ref: /schemas/types.yaml#/definitions/string +description: The coefficient table for the filters + + fsl,asrc-rate: +$ref: /schemas/types.yaml#/definitions/uint32 +description: Defines a mutual sample rate used by DPCM Back Ends + + fsl,asrc-format: +$ref: /schemas/types.yaml#/definitions/uint32 +description: Defines a mutual sample format used by DPCM Back Ends + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - dmas + - dma-name + - fsl,easrc-ram-script-name + - fsl,asrc-rate + - fsl,asrc-format + +examples: + - | +#include + +easrc: easrc@300C { + compatible = "fsl,imx8mn-easrc"; + reg = <0x0 0x300C 0x0 0x1>; + interrupts = <0x0 122 0x4>; + clocks = <&clk IMX8MN_CLK_ASRC_ROOT>; + clock-names = "mem"; + dmas = <&sdma2 16 23 0> , <&sdma2 17 23 0>, + <&sdma2 18 23 0> , <&sdma2 19 23 0>, + <&sdma2 20 23 0> , <&sdma2 21 23 0>, + <&sdma2 22 23 0> , <&sdma2 23 23 0>; + dma-names = "ctx0_rx", "ctx0_tx", + "ctx1_rx", "ctx1_tx", + "ctx2_rx", "ctx2_tx", + "ctx3_rx", "ctx3_tx"; + fsl,easrc-ram-script-name = "imx/easrc/easrc-imx8mn.bin"; + fsl,asrc-rate = <8000>; + fsl,asrc-format = <2>; + status = "disabled"; +}; -- 2.21.0
[PATCH v4 5/8] ASoC: fsl_asrc: rename asrc_priv to asrc
In order to move common structure to fsl_asrc_common.h we change the name of asrc_priv to asrc, the asrc_priv will be used by new struct fsl_asrc_priv. Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_asrc.c | 300 +-- sound/soc/fsl/fsl_asrc.h | 4 +- sound/soc/fsl/fsl_asrc_dma.c | 24 +-- 3 files changed, 164 insertions(+), 164 deletions(-) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 3460ff7f92e2..1ae4b863eadd 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -21,10 +21,10 @@ #define IDEAL_RATIO_DECIMAL_DEPTH 26 #define pair_err(fmt, ...) \ - dev_err(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) + dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) #define pair_dbg(fmt, ...) \ - dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) + dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) /* Corresponding to process_option */ static unsigned int supported_asrc_rate[] = { @@ -157,15 +157,15 @@ static void fsl_asrc_sel_proc(int inrate, int outrate, int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair) { enum asrc_pair_index index = ASRC_INVALID_PAIR; - struct fsl_asrc *asrc_priv = pair->asrc_priv; - struct device *dev = &asrc_priv->pdev->dev; + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->pdev->dev; unsigned long lock_flags; int i, ret = 0; - spin_lock_irqsave(&asrc_priv->lock, lock_flags); + spin_lock_irqsave(&asrc->lock, lock_flags); for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) { - if (asrc_priv->pair[i] != NULL) + if (asrc->pair[i] != NULL) continue; index = i; @@ -177,17 +177,17 @@ int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair) if (index == ASRC_INVALID_PAIR) { dev_err(dev, "all pairs are busy now\n"); ret = -EBUSY; - } else if (asrc_priv->channel_avail < channels) { + } else if (asrc->channel_avail < channels) { dev_err(dev, "can't afford required channels: %d\n", channels); ret = -EINVAL; } else { - asrc_priv->channel_avail -= channels; - asrc_priv->pair[index] = pair; + asrc->channel_avail -= channels; + asrc->pair[index] = pair; pair->channels = channels; pair->index = index; } - spin_unlock_irqrestore(&asrc_priv->lock, lock_flags); + spin_unlock_irqrestore(&asrc->lock, lock_flags); return ret; } @@ -195,25 +195,25 @@ int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair) /** * Release ASRC pair * - * It clears the resource from asrc_priv and releases the occupied channels. + * It clears the resource from asrc and releases the occupied channels. */ void fsl_asrc_release_pair(struct fsl_asrc_pair *pair) { - struct fsl_asrc *asrc_priv = pair->asrc_priv; + struct fsl_asrc *asrc = pair->asrc; enum asrc_pair_index index = pair->index; unsigned long lock_flags; /* Make sure the pair is disabled */ - regmap_update_bits(asrc_priv->regmap, REG_ASRCTR, + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEi_MASK(index), 0); - spin_lock_irqsave(&asrc_priv->lock, lock_flags); + spin_lock_irqsave(&asrc->lock, lock_flags); - asrc_priv->channel_avail += pair->channels; - asrc_priv->pair[index] = NULL; + asrc->channel_avail += pair->channels; + asrc->pair[index] = NULL; pair->error = 0; - spin_unlock_irqrestore(&asrc_priv->lock, lock_flags); + spin_unlock_irqrestore(&asrc->lock, lock_flags); } /** @@ -221,10 +221,10 @@ void fsl_asrc_release_pair(struct fsl_asrc_pair *pair) */ static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out) { - struct fsl_asrc *asrc_priv = pair->asrc_priv; + struct fsl_asrc *asrc = pair->asrc; enum asrc_pair_index index = pair->index; - regmap_update_bits(asrc_priv->regmap, REG_ASRMCR(index), + regmap_update_bits(asrc->regmap, REG_ASRMCR(index), ASRMCRi_EXTTHRSHi_MASK | ASRMCRi_INFIFO_THRESHOLD_MASK | ASRMCRi_OUTFIFO_THRESHOLD_MASK, @@ -257,7 +257,7 @@ static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div) static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair, int inrate, int outrate) { - struct fsl_asrc *asrc_priv = pair->asrc_priv; + struct fsl_asrc *asrc = pair->asrc; enum asrc_pair_index index = pair->index; unsigned long ratio; int i; @@ -286,8 +286,8 @@
[PATCH v4 4/8] ASoC: fsl_asrc: Change asrc_width to asrc_format
asrc_format is more inteligent, which is align with the alsa definition snd_pcm_format_t, we don't need to convert it to format in driver, and it can distinguish S24_LE & S24_3LE. Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_asrc.c | 19 ++- sound/soc/fsl/fsl_asrc.h | 4 ++-- sound/soc/fsl/fsl_asrc_dma.c | 15 --- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 0dcebc24c312..3460ff7f92e2 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -589,7 +589,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, unsigned int channels = params_channels(params); unsigned int rate = params_rate(params); struct asrc_config config; - snd_pcm_format_t format; int ret; ret = fsl_asrc_request_pair(channels, pair); @@ -600,11 +599,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, pair->config = &config; - if (asrc_priv->asrc_width == 16) - format = SNDRV_PCM_FORMAT_S16_LE; - else - format = SNDRV_PCM_FORMAT_S24_LE; - config.pair = pair->index; config.channel_num = channels; config.inclk = INCLK_NONE; @@ -612,11 +606,11 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { config.input_format = params_format(params); - config.output_format = format; + config.output_format = asrc_priv->asrc_format; config.input_sample_rate = rate; config.output_sample_rate = asrc_priv->asrc_rate; } else { - config.input_format = format; + config.input_format = asrc_priv->asrc_format; config.output_format = params_format(params); config.input_sample_rate = asrc_priv->asrc_rate; config.output_sample_rate = rate; @@ -1052,16 +1046,15 @@ static int fsl_asrc_probe(struct platform_device *pdev) return ret; } - ret = of_property_read_u32(np, "fsl,asrc-width", - &asrc_priv->asrc_width); + ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_priv->asrc_format); if (ret) { dev_err(&pdev->dev, "failed to get output width\n"); return ret; } - if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) { - dev_warn(&pdev->dev, "unsupported width, switching to 24bit\n"); - asrc_priv->asrc_width = 24; + if (!(FSL_ASRC_FORMATS & (1ULL << asrc_priv->asrc_format))) { + dev_warn(&pdev->dev, "unsupported format, switching to S24_LE\n"); + asrc_priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; } platform_set_drvdata(pdev, asrc_priv); diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 8a821132d9d0..4940fa0a7542 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -493,7 +493,7 @@ struct fsl_asrc_pair { * @channel_avail: non-occupied channel numbers * @clk_map: clock map for input/output clock * @asrc_rate: default sample rate for ASoC Back-Ends - * @asrc_width: default sample width for ASoC Back-Ends + * @asrc_format: default sample format for ASoC Back-Ends * @regcache_cfg: store register value of REG_ASRCFG */ struct fsl_asrc { @@ -514,7 +514,7 @@ struct fsl_asrc { unsigned char *clk_map[2]; int asrc_rate; - int asrc_width; + snd_pcm_format_t asrc_format; u32 regcache_cfg; }; diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 44e5924be870..af6b583aa71e 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -146,7 +146,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, struct device *dev_be; u8 dir = tx ? OUT : IN; dma_cap_mask_t mask; - int ret; + int ret, bits; /* Fetch the Back-End dma_data from DPCM */ for_each_dpcm_be(rtd, stream, dpcm) { @@ -230,10 +230,19 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, return -EINVAL; } - if (asrc_priv->asrc_width == 16) + bits = snd_pcm_format_physical_width(asrc_priv->asrc_format); + if (bits < 8 || bits > 64) + return -EINVAL; + else if (bits == 8) + buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; + else if (bits == 16) buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; - else + else if (bits == 24) + buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES; + else if (bits <= 32) buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; + else + buswidth = DMA_SLAVE_BUSWIDTH_8_BYTES; config
[PATCH v4 3/8] ASoC: fsl-asoc-card: Change asrc-width to asrc-format
asrc_format is more inteligent, which is align with the alsa definition snd_pcm_format_t, we don't need to convert it to format in driver, and it can distinguish S24_LE & S24_3LE. Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl-asoc-card.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 9ce55feaac22..ab21fa1cabf7 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -680,17 +680,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) goto asrc_fail; } - ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width); + ret = of_property_read_u32(asrc_np, "fsl,asrc-format", &priv->asrc_format); if (ret) { - dev_err(&pdev->dev, "failed to get output rate\n"); + dev_err(&pdev->dev, "failed to get output format\n"); ret = -EINVAL; goto asrc_fail; } - - if (width == 24) - priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; - else - priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; } /* Finish card registering */ -- 2.21.0
[PATCH v4 1/8] ASoC: dt-bindings: fsl_asrc: Change asrc-width to asrc-format
asrc_format is more inteligent, which is align with the alsa definition snd_pcm_format_t, we don't need to convert it to format in driver, and it can distinguish S24_LE & S24_3LE. Signed-off-by: Shengjiu Wang --- Documentation/devicetree/bindings/sound/fsl,asrc.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt index cb9a25165503..0cbb86c026d5 100644 --- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt +++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt @@ -38,7 +38,9 @@ Required properties: - fsl,asrc-rate : Defines a mutual sample rate used by DPCM Back Ends. - - fsl,asrc-width: Defines a mutual sample width used by DPCM Back Ends. + - fsl,asrc-format : Defines a mutual sample format used by DPCM Back + Ends. The value is one of SNDRV_PCM_FORMAT_XX in + "include/uapi/sound/asound.h" - fsl,asrc-clk-map : Defines clock map used in driver. which is required by imx8qm/imx8qxp platform -- 2.21.0
[PATCH v4 2/8] ARM: dts: imx6qdl: Change asrc-width to asrc-format
asrc_format is more inteligent, which is align with the alsa definition snd_pcm_format_t, we don't need to convert it to format in driver, and it can distinguish S24_LE & S24_3LE. default value is SNDRV_PCM_FORMAT_S16_LE(2). Signed-off-by: Shengjiu Wang --- arch/arm/boot/dts/imx6qdl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index e6b4b8525f98..062d98ee513b 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -481,7 +481,7 @@ dma-names = "rxa", "rxb", "rxc", "txa", "txb", "txc"; fsl,asrc-rate = <48000>; - fsl,asrc-width = <16>; + fsl,asrc-format = <2>; status = "okay"; }; -- 2.21.0
[PATCH v4 0/8] ASoC: Add new module driver for new ASRC
Add new module driver for new ASRC in i.MX8MN, several commits are added for change DT binding asrc-width to asrc-format Shengjiu Wang (8): ASoC: dt-bindings: fsl_asrc: Change asrc-width to asrc-format ARM: dts: imx6qdl: Change asrc-width to asrc-format ASoC: fsl-asoc-card: Change asrc-width to asrc-format ASoC: fsl_asrc: Change asrc_width to asrc_format ASoC: fsl_asrc: rename asrc_priv to asrc ASoC: fsl_asrc: Move common definition to fsl_asrc_common ASoC: dt-bindings: fsl_easrc: Add document for EASRC ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers changes in v4 - Add several commit for changing DT binding asrc-width to asrc-format - rename asrc_priv to asrc changes in v3 - add new commit "ASoC: fsl_asrc: Change asrc_width to asrc_format" - modify binding doc to yaml format - remove fsl_easrc_dma.c, make fsl_asrc_dma.c useable for easrc. changes in v2 - change i.MX815 to i.MX8MN - Add changes in Kconfig and Makefile .../devicetree/bindings/sound/fsl,asrc.txt|4 +- .../devicetree/bindings/sound/fsl,easrc.yaml | 96 + arch/arm/boot/dts/imx6qdl.dtsi|2 +- sound/soc/fsl/Kconfig | 11 + sound/soc/fsl/Makefile|2 + sound/soc/fsl/fsl-asoc-card.c |9 +- sound/soc/fsl/fsl_asrc.c | 282 +-- sound/soc/fsl/fsl_asrc.h | 74 +- sound/soc/fsl/fsl_asrc_common.h | 105 + sound/soc/fsl/fsl_asrc_dma.c | 54 +- sound/soc/fsl/fsl_easrc.c | 2111 + sound/soc/fsl/fsl_easrc.h | 651 + 12 files changed, 3169 insertions(+), 232 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.yaml create mode 100644 sound/soc/fsl/fsl_asrc_common.h create mode 100644 sound/soc/fsl/fsl_easrc.c create mode 100644 sound/soc/fsl/fsl_easrc.h -- 2.21.0
Re: [PATCH 8/8] powerpc: Update 83xx/85xx MAINTAINERS entry
On Tue, 2020-02-25 at 10:31 +1100, Michael Ellerman wrote: > Scott said he was still maintaining this "sort of", so change the > status to Odd Fixes. > > Kumar has long ago moved on to greener pastures. > > Remove the dead penguinppc.org link. > > Cc: Scott Wood > Cc: Kumar Gala > Signed-off-by: Michael Ellerman > --- > MAINTAINERS | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index febffee28d00..2e917116ef6a 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -9650,11 +9650,9 @@ F: arch/powerpc/platforms/44x/ > > LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX > M: Scott Wood > -M: Kumar Gala > -W: http://www.penguinppc.org/ > L: linuxppc-dev@lists.ozlabs.org > T: git git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git > -S: Maintained > +S: Odd fixes Acked-by: Scott Wood -Scott
Re: [PATCH 2/2] powerpc/83xx: Add some error handling in 'quirk_mpc8360e_qe_enet10()'
On Sat, 2020-02-08 at 15:09 +0100, Christophe JAILLET wrote: > In some error handling path, we should call "of_node_put(np_par)" or > some resource may be leaking in case of error. > > Fixes: 8159df72d43e ("83xx: add support for the kmeter1 board.") > Signed-off-by: Christophe JAILLET > --- > arch/powerpc/platforms/83xx/km83xx.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > Both patches: Acked-by: Scott Wood > diff --git a/arch/powerpc/platforms/83xx/km83xx.c > b/arch/powerpc/platforms/83xx/km83xx.c > index 306be75faec7..bcdc2c203ec9 100644 > --- a/arch/powerpc/platforms/83xx/km83xx.c > +++ b/arch/powerpc/platforms/83xx/km83xx.c > @@ -60,10 +60,12 @@ static void quirk_mpc8360e_qe_enet10(void) > ret = of_address_to_resource(np_par, 0, &res); > if (ret) { > pr_warn("%s couldn't map par_io registers\n", __func__); > - return; > + goto out; > } > > base = ioremap(res.start, resource_size(&res)); > + if (!base) > + goto out; > > /* >* set output delay adjustments to default values according > @@ -111,6 +113,7 @@ static void quirk_mpc8360e_qe_enet10(void) > setbits32((base + 0xac), 0xc000); > } > iounmap(base); > +out: > of_node_put(np_par); > } >
Re: Re: [PATCH] powerpc/Kconfig: Make FSL_85XX_CACHE_SRAM configurable
On Tue, 2020-01-21 at 14:38 +0800, 王文虎 wrote: > 发件人:Scott Wood > 发送日期:2020-01-21 13:49:59 > 收件人:"王文虎" > 抄送人:wangwenhu ,Kumar Gala ,B > enjamin Herrenschmidt ,Paul Mackerras < > pau...@samba.org>,Michael Ellerman , > linuxppc-dev@lists.ozlabs.org,linux-ker...@vger.kernel.org, > triv...@kernel.org,Rai Harninder > 主题:Re: [PATCH] powerpc/Kconfig: Make FSL_85XX_CACHE_SRAM configurable>On > Tue, 2020-01-21 at 13:20 +0800, 王文虎 wrote: > > > From: Scott Wood > > > Date: 2020-01-21 11:25:25 > > > To: wangwenhu ,Kumar Gala < > > > ga...@kernel.crashing.org>, > > > Benjamin Herrenschmidt ,Paul Mackerras < > > > pau...@samba.org>,Michael Ellerman , > > > linuxppc-dev@lists.ozlabs.org,linux-ker...@vger.kernel.org > > > Cc: triv...@kernel.org,wenhu.w...@vivo.com,Rai Harninder < > > > harninder@nxp.com> > > > Subject: Re: [PATCH] powerpc/Kconfig: Make FSL_85XX_CACHE_SRAM > > > configurable>On Mon, 2020-01-20 at 06:43 -0800, wangwenhu wrote: > > > > > From: wangwenhu > > > > > > > > > > When generating .config file with menuconfig on Freescale BOOKE > > > > > SOC, FSL_85XX_CACHE_SRAM is not configurable for the lack of > > > > > description in the Kconfig field, which makes it impossible > > > > > to support L2Cache-Sram driver. Add a description to make it > > > > > configurable. > > > > > > > > > > Signed-off-by: wangwenhu > > > > > > > > The intent was that drivers using the SRAM API would select the > > > > symbol. What > > > > is the use case for selecting it manually? > > > > > > > > > > With a repository of multiple products(meaning different defconfigs) and > > > multiple > > > developers, the Kconfigs of the Kernel Source Tree change frequently. So > > > the > > > "make menuconfig" > > > process is needed for defconfigs' re-generating or updating for the > > > complexity of dependencies > > > between different features defined in the Kconfigs. > > > > That doesn't answer my question of how the SRAM code would be useful other > > than to some other driver that uses the API (which would use > > "select"). There > > is no userspace API. You could use the kernel command line to configure > > the > > SRAM but you need to get the address of it for it to be useful. > > > > Like you've asked below, via /dev/mem or direct calling within the Kernel. > And they are not submitted yes, under development. If they are calling within the kernel, then whatever driver that is should select FSL_85XX_CACHE_SRAM. Directly accessing /dev/mem without any way for the kernel to advertise where it is or which parts of SRAM are available for use sounds like a bad idea. -Scott
Re: [PATCH] powerpc/fsl_booke: avoid creating duplicate tlb1 entry
On Thu, 2020-01-23 at 11:19 +, Laurentiu Tudor wrote: > In the current implementation, the call to loadcam_multi() is wrapped > between switch_to_as1() and restore_to_as0() calls so, when it tries > to create its own temporary AS=1 TLB1 entry, it ends up duplicating the > existing one created by switch_to_as1(). Add a check to skip creating > the temporary entry if already running in AS=1. > > Fixes: d9e1831a4202 ("powerpc/85xx: Load all early TLB entries at once") > Signed-off-by: Laurentiu Tudor > Cc: sta...@vger.kernel.org > --- > arch/powerpc/mm/nohash/tlb_low.S | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) Assuming you've tested this on all combinations of 32/64 relocatable and not: Acked-by: Scott Wood -Scott
Re: [PATCH v3 0/6] implement KASLR for powerpc/fsl_booke/64
On Sat, 2020-02-29 at 15:27 +0800, Jason Yan wrote: > > 在 2020/2/29 12:28, Scott Wood 写道: > > On Fri, 2020-02-28 at 14:47 +0800, Jason Yan wrote: > > > > > > 在 2020/2/28 13:53, Scott Wood 写道: > > > > > > > > I don't see any debug setting for %pK (or %p) to always print the > > > > actual > > > > address (closest is kptr_restrict=1 but that only works in certain > > > > contexts)... from looking at the code it seems it hashes even if kaslr > > > > is > > > > entirely disabled? Or am I missing something? > > > > > > > > > > Yes, %pK (or %p) always hashes whether kaslr is disabled or not. So if > > > we want the real value of the address, we cannot use it. But if you only > > > want to distinguish if two pointers are the same, it's ok. > > > > Am I the only one that finds this a bit crazy? If you want to lock a > > system > > down then fine, but why wage war on debugging even when there's no > > randomization going on? Comparing two pointers for equality is not always > > adequate. > > > > AFAIK, %p hashing is only exist because of many legacy address printings > and force who really want the raw values to switch to %px or even %lx. > It's not the opposite of debugging. Raw address printing is not > forbidden, only people need to estimate the risk of adrdress leaks. Yes, but I don't see any format specifier to switch to that will hash in a randomized production environment, but not in a debug or other non-randomized environment which seems like the ideal default for most debug output. > > Turnning to %p may not be a good idea in this situation. So > for the REG logs printed when dumping stack, we can disable it when > KASLR is open. For the REG logs in other places like show_regs(), only > privileged can trigger it, and they are not combind with a symbol, so > I think it's ok to keep them. > > diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c > index fad50db9dcf2..659c51f0739a 100644 > --- a/arch/powerpc/kernel/process.c > +++ b/arch/powerpc/kernel/process.c > @@ -2068,7 +2068,10 @@ void show_stack(struct task_struct *tsk, unsigned > long *stack) > newsp = stack[0]; > ip = stack[STACK_FRAME_LR_SAVE]; > if (!firstframe || ip != lr) { > - printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); > + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) > + printk("%pS", (void *)ip); > + else > + printk("["REG"] ["REG"] %pS", sp, ip, > (void *)ip); This doesn't deal with "nokaslr" on the kernel command line. It also doesn't seem like something that every callsite should have to opencode, versus having an appropriate format specifier behaves as I described above (and I still don't see why that format specifier should not be "%p"). -Scott
RE: [RFC PATCH v1] powerpc/prom_init: disable XIVE in Secure VM.
On Sat, Feb 29, 2020 at 09:27:54AM +0100, Cédric Le Goater wrote: > On 2/29/20 8:54 AM, Ram Pai wrote: > > XIVE is not correctly enabled for Secure VM in the KVM Hypervisor yet. > > > > Hence Secure VM, must always default to XICS interrupt controller. > > have you tried XIVE emulation 'kernel-irqchip=off' ? yes and it hangs. I think that option, continues to enable some variant of XIVE in the VM. There are some known deficiencies between KVM and the ultravisor negotiation, resulting in a hang in the SVM. > > > If XIVE is requested through kernel command line option "xive=on", > > override and turn it off. > > This is incorrect. It is negotiated through CAS depending on the FW > capabilities and the KVM capabilities. Yes I understand, qemu/KVM have predetermined a set of capabilties that it can offer to the VM. The kernel within the VM has a list of capabilties it needs to operate correctly. So both negotiate and determine something mutually ammicable. Here I am talking about the list of capabilities that the kernel is trying to determine, it needs to operate correctly. "xive=on" is one of those capabilities the kernel is told by the VM-adminstrator, to enable. Unfortunately if the VM-administrtor blindly requests to enable it, the kernel must override it, if it knows that will be switching the VM into a SVM soon. No point negotiating a capability with Qemu; through CAS, if it knows it cannot handle that capability. > > > If XIVE is the only supported platform interrupt controller; specified > > through qemu option "ic-mode=xive", simply abort. Otherwise default to > > XICS. > > > I don't think it is a good approach to downgrade the guest kernel > capabilities this way. > > PAPR has specified the CAS negotiation process for this purpose. It > comes in two parts under KVM. First the KVM hypervisor advertises or > not a capability to QEMU. The second is the CAS negotiation process > between QEMU and the guest OS. Unfortunately, this is not viable. At the time the hypervisor advertises its capabilities to qemu, the hypervisor has no idea whether that VM will switch into a SVM or not. The decision to switch into a SVM is taken by the kernel running in the VM. This happens much later, after the hypervisor has already conveyed its capabilties to the qemu, and qemu has than instantiated the VM. As a result, CAS in prom_init is the only place where this negotiation can take place. > > The SVM specifications might not be complete yet and if some features > are incompatible, I think we should modify the capabilities advertised > by the hypervisor : no XIVE in case of SVM. QEMU will automatically > use the fallback path and emulate the XIVE device, same as setting > 'kernel-irqchip=off'. As mentioned above, this would be an excellent approach, if the Hypervisor was aware of the VM's intent to switch into a SVM. Neither the hypervisor knows, nor the qemu. Only the kernel running within the VM knows about it. Do you still think, my approach is wrong? RP
Re: [PATCH v3 7/7] mm/memremap: Set caching mode for PCI P2PDMA memory to WC
On Fri, Feb 21, 2020 at 10:25 AM Logan Gunthorpe wrote: > > PCI BAR IO memory should never be mapped as WB, however prior to this > the PAT bits were set WB and it was typically overridden by MTRR > registers set by the firmware. > > Set PCI P2PDMA memory to be WC (writecombining) as the only current > user (the NVMe CMB) was originally mapped WC before the P2PDMA code > replaced the mapping with devm_memremap_pages(). Will the change to UC regress this existing use case? > > Future use-cases may need to generalize this by adding flags to > select the caching type, as some P2PDMA cases will not want WC. > However, those use-cases are not upstream yet and this can be changed > when they arrive. > > Cc: Dan Williams > Cc: Christoph Hellwig > Cc: Jason Gunthorpe > Signed-off-by: Logan Gunthorpe > --- > mm/memremap.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/mm/memremap.c b/mm/memremap.c > index 06742372a203..8d141c3e3364 100644 > --- a/mm/memremap.c > +++ b/mm/memremap.c > @@ -190,7 +190,10 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid) > } > break; > case MEMORY_DEVICE_DEVDAX: > + need_devmap_managed = false; > + break; > case MEMORY_DEVICE_PCI_P2PDMA: > + params.pgprot = pgprot_writecombine(params.pgprot); Approach looks good to me, modulo Jason's comment that this should be UC. Upcoming DAX changes will want to pass this via pgmap, but as you say this can wait for this changes to arrive. After change to UC: Reviewed-by: Dan Williams
Re: [PATCH v3 6/7] mm/memory_hotplug: Add pgprot_t to mhp_params
On Fri, Feb 21, 2020 at 10:25 AM Logan Gunthorpe wrote: > > devm_memremap_pages() is currently used by the PCI P2PDMA code to create > struct page mappings for IO memory. At present, these mappings are created > with PAGE_KERNEL which implies setting the PAT bits to be WB. However, on > x86, an mtrr register will typically override this and force the cache > type to be UC-. In the case firmware doesn't set this register it is > effectively WB and will typically result in a machine check exception > when it's accessed. > > Other arches are not currently likely to function correctly seeing they > don't have any MTRR registers to fall back on. > > To solve this, provide a way to specify the pgprot value explicitly to > arch_add_memory(). > > Of the arches that support MEMORY_HOTPLUG: x86_64, and arm64 need a simple > change to pass the pgprot_t down to their respective functions which set > up the page tables. For x86_32, set the page tables explicitly using > _set_memory_prot() (seeing they are already mapped). For ia64, s390 and > sh, reject anything but PAGE_KERNEL settings -- this should be fine, > for now, seeing these architectures don't support ZONE_DEVICE. > > A check in __add_pages() is also added to ensure the pgprot parameter was > set for all arches. > > Cc: Dan Williams > Signed-off-by: Logan Gunthorpe > Acked-by: David Hildenbrand > Acked-by: Michal Hocko > --- > arch/arm64/mm/mmu.c| 3 ++- > arch/ia64/mm/init.c| 3 +++ > arch/powerpc/mm/mem.c | 3 ++- > arch/s390/mm/init.c| 3 +++ > arch/sh/mm/init.c | 3 +++ > arch/x86/mm/init_32.c | 5 + > arch/x86/mm/init_64.c | 2 +- > include/linux/memory_hotplug.h | 2 ++ > mm/memory_hotplug.c| 5 - > mm/memremap.c | 6 +++--- > 10 files changed, 28 insertions(+), 7 deletions(-) > > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > index ee37bca8aba8..ea3fa844a8a2 100644 > --- a/arch/arm64/mm/mmu.c > +++ b/arch/arm64/mm/mmu.c > @@ -1058,7 +1058,8 @@ int arch_add_memory(int nid, u64 start, u64 size, > flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; > > __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), > -size, PAGE_KERNEL, __pgd_pgtable_alloc, flags); > +size, params->pgprot, __pgd_pgtable_alloc, > +flags); > > memblock_clear_nomap(start, size); > > diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c > index 97bbc23ea1e3..d637b4ea3147 100644 > --- a/arch/ia64/mm/init.c > +++ b/arch/ia64/mm/init.c > @@ -676,6 +676,9 @@ int arch_add_memory(int nid, u64 start, u64 size, > unsigned long nr_pages = size >> PAGE_SHIFT; > int ret; > > + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)) > + return -EINVAL; > + > ret = __add_pages(nid, start_pfn, nr_pages, params); > if (ret) > printk("%s: Problem encountered in __add_pages() as ret=%d\n", > diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c > index 19b1da5d7eca..832412bc7fad 100644 > --- a/arch/powerpc/mm/mem.c > +++ b/arch/powerpc/mm/mem.c > @@ -138,7 +138,8 @@ int __ref arch_add_memory(int nid, u64 start, u64 size, > resize_hpt_for_hotplug(memblock_phys_mem_size()); > > start = (unsigned long)__va(start); > - rc = create_section_mapping(start, start + size, nid, PAGE_KERNEL); > + rc = create_section_mapping(start, start + size, nid, > + params->pgprot); > if (rc) { > pr_warn("Unable to create mapping for hot added memory > 0x%llx..0x%llx: %d\n", > start, start + size, rc); > diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c > index e9e4a7abd0cc..87b2d024e75a 100644 > --- a/arch/s390/mm/init.c > +++ b/arch/s390/mm/init.c > @@ -277,6 +277,9 @@ int arch_add_memory(int nid, u64 start, u64 size, > if (WARN_ON_ONCE(params->altmap)) > return -EINVAL; > > + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)) > + return -EINVAL; > + > rc = vmem_add_mapping(start, size); > if (rc) > return rc; > diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c > index e5114c053364..b9de2d4fa57e 100644 > --- a/arch/sh/mm/init.c > +++ b/arch/sh/mm/init.c > @@ -412,6 +412,9 @@ int arch_add_memory(int nid, u64 start, u64 size, > unsigned long nr_pages = size >> PAGE_SHIFT; > int ret; > > + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot) > + return -EINVAL; > + > /* We only have ZONE_NORMAL, so this is easy.. */ > ret = __add_pages(nid, start_pfn, nr_pages, params); > if (unlikely(ret)) > diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c > index e25a4218e6ff..96d8e4fb1cc8 100644 > --- a/arch/x86/mm/init_32.c > +++ b/ar
Re: [PATCH v3 3/7] x86/mm: Thread pgprot_t through init_memory_mapping()
On Fri, Feb 21, 2020 at 10:25 AM Logan Gunthorpe wrote: > > In prepartion to support a pgprot_t argument for arch_add_memory(). > > It's required to move the prototype of init_memory_mapping() seeing > the original location came before the definition of pgprot_t. > > Cc: Thomas Gleixner > Cc: Ingo Molnar > Cc: Borislav Petkov > Cc: "H. Peter Anvin" > Cc: x...@kernel.org > Cc: Dave Hansen > Cc: Andy Lutomirski > Cc: Peter Zijlstra > Signed-off-by: Logan Gunthorpe Looks good, checked for argument confusion, passes the nvdimm unit tests. Reviewed-by: Dan Williams
Re: [PATCH v3 4/7] x86/mm: Introduce _set_memory_prot()
On Fri, Feb 21, 2020 at 10:25 AM Logan Gunthorpe wrote: > > For use in the 32bit arch_add_memory() to set the pgprot type of the > memory to add. > > Cc: Thomas Gleixner > Cc: Ingo Molnar > Cc: Borislav Petkov > Cc: "H. Peter Anvin" > Cc: x...@kernel.org > Cc: Dave Hansen > Cc: Andy Lutomirski > Cc: Peter Zijlstra > Signed-off-by: Logan Gunthorpe > --- > arch/x86/include/asm/set_memory.h | 1 + > arch/x86/mm/pat/set_memory.c | 7 +++ > 2 files changed, 8 insertions(+) > > diff --git a/arch/x86/include/asm/set_memory.h > b/arch/x86/include/asm/set_memory.h > index 64c3dce374e5..0aca959cf9a4 100644 > --- a/arch/x86/include/asm/set_memory.h > +++ b/arch/x86/include/asm/set_memory.h > @@ -34,6 +34,7 @@ > * The caller is required to take care of these. > */ > > +int _set_memory_prot(unsigned long addr, int numpages, pgprot_t prot); I wonder if this should be separated from the naming convention of the other routines because this is only an internal helper for code paths where the prot was established by an upper layer. For example, I expect that the kernel does not want new usages to make the mistake of calling: _set_memory_prot(..., pgprot_writecombine(pgprot)) ...instead of _set_memory_wc() I'm thinking just a double underscore rename (__set_memory_prot) and a kerneldoc comment for that pointing people to use the direct _set_memory_ helpers. With that you can add: Reviewed-by: Dan Williams
Re: [PATCH v3 2/7] mm/memory_hotplug: Rename mhp_restrictions to mhp_params
On Fri, Feb 21, 2020 at 10:25 AM Logan Gunthorpe wrote: > > The mhp_restrictions struct really doesn't specify anything resembling > a restriction anymore so rename it to be mhp_params as it is a list > of extended parameters. > > Signed-off-by: Logan Gunthorpe Tests ok, and looks good to me: Reviewed-by: Dan Williams
Re: [PATCH 6/8] powerpc: Update MPC5XXX MAINTAINERS entry
On Tue, 25 Feb 2020 10:31:44 +1100 Michael Ellerman m...@ellerman.id.au wrote: >It's several years since the last commit from Anatolij, so mark >MPC5XXX as "Odd Fixes" rather than "Maintained". > >Also the git link no longer works so remove it. > >Cc: Anatolij Gustschin >Signed-off-by: Michael Ellerman Acked-by: Anatolij Gustschin
[PATCH V2 9/9] Documentation/powerpc: VAS API
Power9 introduced Virtual Accelerator Switchboard (VAS) which allows userspace to communicate with Nest Accelerator (NX) directly. But kernel has to establish channel to NX for userspace. This document describes user space API that application can use to establish communication channel. Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Haren Myneni --- Documentation/powerpc/index.rst | 1 + Documentation/powerpc/vas-api.rst | 246 ++ 2 files changed, 247 insertions(+) create mode 100644 Documentation/powerpc/vas-api.rst diff --git a/Documentation/powerpc/index.rst b/Documentation/powerpc/index.rst index 0d45f0f..afe2d5e 100644 --- a/Documentation/powerpc/index.rst +++ b/Documentation/powerpc/index.rst @@ -30,6 +30,7 @@ powerpc syscall64-abi transactional_memory ultravisor +vas-api .. only:: subproject and html diff --git a/Documentation/powerpc/vas-api.rst b/Documentation/powerpc/vas-api.rst new file mode 100644 index 000..13ce4e7 --- /dev/null +++ b/Documentation/powerpc/vas-api.rst @@ -0,0 +1,246 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. _VAS-API: + +=== +Virtual Accelerator Switchboard (VAS) userspace API +=== + +Introduction + + +Power9 processor introduced Virtual Accelerator Switchboard (VAS) which +allows both userspace and kernel communicate to co-processor +(hardware accelerator) referred to as the Nest Accelerator (NX). The NX +unit comprises of one or more hardware engines or co-processor types +such as 842 compression, GZIP compression and encryption. On power9, +userspace applications will have access to only GZIP Compression engine +which supports ZLIB and GZIP compression algorithms in the hardware. + +To communicate with NX, kernel has to establish a channel or window and +then requests can be submitted directly without kernel involvement. +Requests to the GZIP engine must be formatted as a co-processor Request +Block (CRB) and these CRBs must be submitted to the NX using COPY/PASTE +instructions to paste the CRB to hardware address that is associated with +the engine's request queue. + +The GZIP engine provides two priority levels of requests: Normal and +High. Only Normal requests are supported from userspace right now. + +This document explains userspace API that is used to interact with +kernel to setup channel / window which can be used to send compression +requests directly to NX accelerator. + + +Overview + + +Application access to the GZIP engine is provided through +/dev/crypto/nx-gzip device node implemented by the VAS/NX device driver. +An application must open the /dev/crypto/nx-gzip device to obtain a file +descriptor (fd). Then should issue VAS_TX_WIN_OPEN ioctl with this fd to +establish connection to the engine. It means send window is opened on GZIP +engine for this process. Once a connection is established, the application +should use the mmap() system call to map the hardware address of engine's +request queue into the application's virtual address space. + +The application can then submit one or more requests to the the engine by +using copy/paste instructions and pasting the CRBs to the virtual address +(aka paste_address) returned by mmap(). User space can close the +established connection or send window by closing the file descriptior +(close(fd)) or upon the process exit. + +Note that applications can send several requests with the same window or +can establish multiple windows, but one window for each file descriptor. + +Following sections provide additional details and references about the +individual steps. + +NX-GZIP Device Node +=== + +There is one /dev/crypto/nx-gzip node in the system and it provides +access to all GZIP engines in the system. The only valid operations on +/dev/crypto/nx-gzip are: + + * open() the device for read and write. + * issue VAS_TX_WIN_OPEN ioctl + * mmap() the engine's request queue into application's virtual + address space (i.e. get a paste_address for the co-processor + engine). + * close the device node. + +Other file operations on this device node are undefined. + +Note that the copy and paste operations go directly to the hardware and +do not go through this device. Refer COPY/PASTE document for more +details. + +Although a system may have several instances of the NX co-processor +engines (typically, one per P9 chip) there is just one +/dev/crypto/nx-gzip device node in the system. When the nx-gzip device +node is opened, Kernel opens send window on a suitable instance of NX +accelerator. It finds CPU on which the user process is executing and +determine the NX instance for the corresponding chip on which this CPU +belongs. + +Applications may chose a specific instance of the NX co-processor using +the vas_id field in the VAS_TX_WIN_OPEN ioctl as detailed below. + +A userspace libr
[PATCH V2 8/9] crypto/nx: Remove 'pid' in vas_tx_win_attr struct
When window is opened, pid reference is taken for user space windows. Not needed for kernel windows. So remove 'pid' in vas_tx_win_attr struct. Signed-off-by: Haren Myneni --- arch/powerpc/include/asm/vas.h| 1 - drivers/crypto/nx/nx-common-powernv.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index e064953..994db6f 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -86,7 +86,6 @@ struct vas_tx_win_attr { int wcreds_max; int lpid; int pidr; /* hardware PID (from SPRN_PID) */ - int pid;/* linux process id */ int pswid; int rsvd_txbuf_count; int tc_mode; diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c index 6848aea1..c8b2e01 100644 --- a/drivers/crypto/nx/nx-common-powernv.c +++ b/drivers/crypto/nx/nx-common-powernv.c @@ -692,7 +692,6 @@ static struct vas_window *nx_alloc_txwin(struct nx_coproc *coproc) */ vas_init_tx_win_attr(&txattr, coproc->ct); txattr.lpid = 0;/* lpid is 0 for kernel requests */ - txattr.pid = 0; /* pid is 0 for kernel requests */ /* * Open a VAS send window which is used to send request to NX. -- 1.8.3.1
[PATCH V2 7/9] crypto/nx: Enable and setup GZIP compression type
Changes to probe GZIP device-tree nodes, open RX windows and setup GZIP compression type. No plans to provide GZIP usage in kernel right now, but this patch enables GZIP for user space usage. Signed-off-by: Haren Myneni --- drivers/crypto/nx/nx-common-powernv.c | 43 ++- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c index 1cd4f40..6848aea1 100644 --- a/drivers/crypto/nx/nx-common-powernv.c +++ b/drivers/crypto/nx/nx-common-powernv.c @@ -65,6 +65,7 @@ struct nx_coproc { * Using same values as in skiboot or coprocessor type representing * in NX workbook. */ +#define NX_CT_GZIP (2) /* on P9 and later */ #define NX_CT_842 (3) static int (*nx842_powernv_exec)(const unsigned char *in, @@ -819,6 +820,9 @@ static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, if (type == NX_CT_842) ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_842_HIPRI, VAS_COP_TYPE_842); + else if (type == NX_CT_GZIP) + ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_GZIP_HIPRI, + VAS_COP_TYPE_GZIP); if (ret) goto err_out; @@ -867,12 +871,16 @@ static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, return ret; } -static int __init nx_coproc_init(int chip_id, int ct_842) +static int __init nx_coproc_init(int chip_id, int ct_842, int ct_gzip) { int ret = 0; if (opal_check_token(OPAL_NX_COPROC_INIT)) { ret = opal_nx_coproc_init(chip_id, ct_842); + + if (!ret) + ret = opal_nx_coproc_init(chip_id, ct_gzip); + if (ret) { ret = opal_error_code(ret); pr_err("Failed to initialize NX for chip(%d): %d\n", @@ -902,8 +910,8 @@ static int __init find_nx_device_tree(struct device_node *dn, int chip_id, static int __init nx_powernv_probe_vas(struct device_node *pn) { int chip_id, vasid, ret = 0; + int ct_842 = 0, ct_gzip = 0; struct device_node *dn; - int ct_842 = 0; chip_id = of_get_ibm_chip_id(pn); if (chip_id < 0) { @@ -920,19 +928,24 @@ static int __init nx_powernv_probe_vas(struct device_node *pn) for_each_child_of_node(pn, dn) { ret = find_nx_device_tree(dn, chip_id, vasid, NX_CT_842, "ibm,p9-nx-842", &ct_842); + + if (!ret) + ret = find_nx_device_tree(dn, chip_id, vasid, + NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip); + if (ret) return ret; } - if (!ct_842) { - pr_err("NX842 FIFO nodes are missing\n"); + if (!ct_842 || !ct_gzip) { + pr_err("NX FIFO nodes are missing\n"); return -EINVAL; } /* * Initialize NX instance for both high and normal priority FIFOs. */ - ret = nx_coproc_init(chip_id, ct_842); + ret = nx_coproc_init(chip_id, ct_842, ct_gzip); return ret; } @@ -1072,10 +1085,19 @@ static __init int nx_compress_powernv_init(void) nx842_powernv_exec = nx842_exec_icswx; } else { /* +* Register VAS user space API for NX GZIP so +* that user space can use GZIP engine. +* 842 compression is supported only in kernel. +*/ + ret = vas_register_coproc_api(THIS_MODULE); + + /* * GZIP is not supported in kernel right now. * So open tx windows only for 842. */ - ret = nx_open_percpu_txwins(); + if (!ret) + ret = nx_open_percpu_txwins(); + if (ret) { nx_delete_coprocs(); return ret; @@ -1096,6 +1118,15 @@ static __init int nx_compress_powernv_init(void) static void __exit nx_compress_powernv_exit(void) { + /* +* GZIP engine is supported only in power9 or later and nx842_ct +* is used on power8 (icswx). +* VAS API for NX GZIP is registered during init for user space +* use. So delete this API use for GZIP engine. +*/ + if (!nx842_ct) + vas_unregister_coproc_api(); + crypto_unregister_alg(&nx842_powernv_alg); nx_delete_coprocs(); -- 1.8.3.1
[PATCH V2 6/9] crypto/nx: Make enable code generic to add new GZIP compression type
Make setup and enable code generic to support new GZIP compression type. Changed nx842 reference to nx and moved some code to new functions. The actual functionality is not changed. Signed-off-by: Haren Myneni --- drivers/crypto/nx/nx-common-powernv.c | 159 +- 1 file changed, 100 insertions(+), 59 deletions(-) diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c index f42881f..1cd4f40 100644 --- a/drivers/crypto/nx/nx-common-powernv.c +++ b/drivers/crypto/nx/nx-common-powernv.c @@ -40,9 +40,9 @@ struct nx842_workmem { char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */ } __packed __aligned(WORKMEM_ALIGN); -struct nx842_coproc { +struct nx_coproc { unsigned int chip_id; - unsigned int ct; + unsigned int ct;/* Can be 842 or GZIP high/normal*/ unsigned int ci;/* Coprocessor instance, used with icswx */ struct { struct vas_window *rxwin; @@ -58,9 +58,15 @@ struct nx842_coproc { static DEFINE_PER_CPU(struct vas_window *, cpu_txwin); /* no cpu hotplug on powernv, so this list never changes after init */ -static LIST_HEAD(nx842_coprocs); +static LIST_HEAD(nx_coprocs); static unsigned int nx842_ct; /* used in icswx function */ +/* + * Using same values as in skiboot or coprocessor type representing + * in NX workbook. + */ +#define NX_CT_842 (3) + static int (*nx842_powernv_exec)(const unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlenp, void *workmem, int fc); @@ -666,15 +672,15 @@ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen, wmem, CCW_FC_842_DECOMP_CRC); } -static inline void nx842_add_coprocs_list(struct nx842_coproc *coproc, +static inline void nx_add_coprocs_list(struct nx_coproc *coproc, int chipid) { coproc->chip_id = chipid; INIT_LIST_HEAD(&coproc->list); - list_add(&coproc->list, &nx842_coprocs); + list_add(&coproc->list, &nx_coprocs); } -static struct vas_window *nx842_alloc_txwin(struct nx842_coproc *coproc) +static struct vas_window *nx_alloc_txwin(struct nx_coproc *coproc) { struct vas_window *txwin = NULL; struct vas_tx_win_attr txattr; @@ -704,9 +710,9 @@ static struct vas_window *nx842_alloc_txwin(struct nx842_coproc *coproc) * cpu_txwin is used in copy/paste operation for each compression / * decompression request. */ -static int nx842_open_percpu_txwins(void) +static int nx_open_percpu_txwins(void) { - struct nx842_coproc *coproc, *n; + struct nx_coproc *coproc, *n; unsigned int i, chip_id; for_each_possible_cpu(i) { @@ -714,17 +720,18 @@ static int nx842_open_percpu_txwins(void) chip_id = cpu_to_chip_id(i); - list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) { + list_for_each_entry_safe(coproc, n, &nx_coprocs, list) { /* * Kernel requests use only high priority FIFOs. So * open send windows for these FIFOs. +* GZIP is not supported in kernel right now. */ if (coproc->ct != VAS_COP_TYPE_842_HIPRI) continue; if (coproc->chip_id == chip_id) { - txwin = nx842_alloc_txwin(coproc); + txwin = nx_alloc_txwin(coproc); if (IS_ERR(txwin)) return PTR_ERR(txwin); @@ -743,13 +750,28 @@ static int nx842_open_percpu_txwins(void) return 0; } +static int __init nx_set_ct(struct nx_coproc *coproc, const char *priority, + int high, int normal) +{ + if (!strcmp(priority, "High")) + coproc->ct = high; + else if (!strcmp(priority, "Normal")) + coproc->ct = normal; + else { + pr_err("Invalid RxFIFO priority value\n"); + return -EINVAL; + } + + return 0; +} + static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, - int vasid, int *ct) + int vasid, int type, int *ct) { struct vas_window *rxwin = NULL; struct vas_rx_win_attr rxattr; - struct nx842_coproc *coproc; u32 lpid, pid, tid, fifo_size; + struct nx_coproc *coproc; u64 rx_fifo; const char *priority; int ret; @@ -794,15 +816,12 @@ static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, if (!coproc) return -ENOMEM; - if (!strcmp(priority, "High")) - coproc->ct = VA
[PATCH V2 5/9] crypto/nx: Rename nx-842-powernv file name to nx-common-powernv
Rename nx-842-powernv.c to nx-common-powernv.c to add code for setup and enable new GZIP compression type. The actual functionality is not changed in this patch. Signed-off-by: Haren Myneni --- drivers/crypto/nx/Makefile|2 +- drivers/crypto/nx/nx-842-powernv.c| 1062 - drivers/crypto/nx/nx-common-powernv.c | 1062 + 3 files changed, 1063 insertions(+), 1063 deletions(-) delete mode 100644 drivers/crypto/nx/nx-842-powernv.c create mode 100644 drivers/crypto/nx/nx-common-powernv.c diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile index 015155d..bc89a20 100644 --- a/drivers/crypto/nx/Makefile +++ b/drivers/crypto/nx/Makefile @@ -15,4 +15,4 @@ obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compres obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o nx-compress-objs := nx-842.o nx-compress-pseries-objs := nx-842-pseries.o -nx-compress-powernv-objs := nx-842-powernv.o +nx-compress-powernv-objs := nx-common-powernv.o diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c deleted file mode 100644 index 8e63326..000 --- a/drivers/crypto/nx/nx-842-powernv.c +++ /dev/null @@ -1,1062 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Driver for IBM PowerNV 842 compression accelerator - * - * Copyright (C) 2015 Dan Streetman, IBM Corp - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "nx-842.h" - -#include - -#include -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Dan Streetman "); -MODULE_DESCRIPTION("842 H/W Compression driver for IBM PowerNV processors"); -MODULE_ALIAS_CRYPTO("842"); -MODULE_ALIAS_CRYPTO("842-nx"); - -#define WORKMEM_ALIGN (CRB_ALIGN) -#define CSB_WAIT_MAX (5000) /* ms */ -#define VAS_RETRIES(10) - -struct nx842_workmem { - /* Below fields must be properly aligned */ - struct coprocessor_request_block crb; /* CRB_ALIGN align */ - struct data_descriptor_entry ddl_in[DDL_LEN_MAX]; /* DDE_ALIGN align */ - struct data_descriptor_entry ddl_out[DDL_LEN_MAX]; /* DDE_ALIGN align */ - /* Above fields must be properly aligned */ - - ktime_t start; - - char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */ -} __packed __aligned(WORKMEM_ALIGN); - -struct nx842_coproc { - unsigned int chip_id; - unsigned int ct; - unsigned int ci;/* Coprocessor instance, used with icswx */ - struct { - struct vas_window *rxwin; - int id; - } vas; - struct list_head list; -}; - -/* - * Send the request to NX engine on the chip for the corresponding CPU - * where the process is executing. Use with VAS function. - */ -static DEFINE_PER_CPU(struct vas_window *, cpu_txwin); - -/* no cpu hotplug on powernv, so this list never changes after init */ -static LIST_HEAD(nx842_coprocs); -static unsigned int nx842_ct; /* used in icswx function */ - -static int (*nx842_powernv_exec)(const unsigned char *in, - unsigned int inlen, unsigned char *out, - unsigned int *outlenp, void *workmem, int fc); - -/** - * setup_indirect_dde - Setup an indirect DDE - * - * The DDE is setup with the the DDE count, byte count, and address of - * first direct DDE in the list. - */ -static void setup_indirect_dde(struct data_descriptor_entry *dde, - struct data_descriptor_entry *ddl, - unsigned int dde_count, unsigned int byte_count) -{ - dde->flags = 0; - dde->count = dde_count; - dde->index = 0; - dde->length = cpu_to_be32(byte_count); - dde->address = cpu_to_be64(nx842_get_pa(ddl)); -} - -/** - * setup_direct_dde - Setup single DDE from buffer - * - * The DDE is setup with the buffer and length. The buffer must be properly - * aligned. The used length is returned. - * Returns: - * NSuccessfully set up DDE with N bytes - */ -static unsigned int setup_direct_dde(struct data_descriptor_entry *dde, -unsigned long pa, unsigned int len) -{ - unsigned int l = min_t(unsigned int, len, LEN_ON_PAGE(pa)); - - dde->flags = 0; - dde->count = 0; - dde->index = 0; - dde->length = cpu_to_be32(l); - dde->address = cpu_to_be64(pa); - - return l; -} - -/** - * setup_ddl - Setup DDL from buffer - * - * Returns: - * 0 Successfully set up DDL - */ -static int setup_ddl(struct data_descriptor_entry *dde, -struct data_descriptor_entry *ddl, -unsigned char *buf, unsigned int len, -bool in) -{ - unsigned long pa = nx842_get_pa(buf); - int i, ret, total_len = len; - - if (!IS_ALIGNED(pa, DDE_BUFFER_ALIGN)) { - pr_debug("%s buffer pa 0x%lx not 0x%x-
[PATCH V2 4/9] crypto/nx: Initialize coproc entry with kzalloc
coproc entry is initialized during NX probe on power9, but not on P8. nx842_delete_coprocs() is used for both and frees receive window if it is allocated. Getting crash for rmmod on P8 since coproc->vas.rxwin is not initialized. This patch replaces kmalloc with kzalloc in nx842_powernv_probe() Signed-off-by: Haren Myneni --- drivers/crypto/nx/nx-842-powernv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index c037a24..8e63326 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -922,7 +922,7 @@ static int __init nx842_powernv_probe(struct device_node *dn) return -EINVAL; } - coproc = kmalloc(sizeof(*coproc), GFP_KERNEL); + coproc = kzalloc(sizeof(*coproc), GFP_KERNEL); if (!coproc) return -ENOMEM; -- 1.8.3.1
[PATCH V3 3/9] powerpc/vas: Add VAS user space API
On power9, userspace can send GZIP compression requests directly to NX once kernel establishes NX channel / window with VAS. This patch provides user space API which allows user space to establish channel using open VAS_TX_WIN_OPEN ioctl, mmap and close operations. Each window corresponds to file descriptor and application can open multiple windows. After the window is opened, VAS_TX_WIN_OPEN icoctl to open a window on specific VAS instance, mmap() system call to map the hardware address of engine's request queue into the application's virtual address space. Then the application can then submit one or more requests to the the engine by using the copy/paste instructions and pasting the CRBs to the virtual address (aka paste_address) returned by mmap(). Only NX GZIP coprocessor type is supported right now and allow GZIP engine access via /dev/crypto/nx-gzip device node. Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Haren Myneni --- arch/powerpc/include/asm/vas.h | 11 ++ arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/vas-api.c| 290 arch/powerpc/platforms/powernv/vas-window.c | 6 +- arch/powerpc/platforms/powernv/vas.h| 2 + 5 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/platforms/powernv/vas-api.c diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index f93e6b0..e064953 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -163,4 +163,15 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, */ int vas_paste_crb(struct vas_window *win, int offset, bool re); +/* + * Register / unregister coprocessor type to VAS API which will be exported + * to user space. Applications can use this API to open / close window + * which can be used to send / receive requests directly to cooprcessor. + * + * Only NX GZIP coprocessor type is supported now, but this API can be + * used for others in future. + */ +int vas_register_coproc_api(struct module *mod); +void vas_unregister_coproc_api(void); + #endif /* __ASM_POWERPC_VAS_H */ diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 395789f..fe3f0fb 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o obj-$(CONFIG_OPAL_PRD) += opal-prd.o obj-$(CONFIG_PERF_EVENTS) += opal-imc.o obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o -obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o vas-fault.o +obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o vas-fault.o vas-api.o obj-$(CONFIG_OCXL_BASE)+= ocxl.o obj-$(CONFIG_SCOM_DEBUGFS) += opal-xscom.o obj-$(CONFIG_PPC_SECURE_BOOT) += opal-secvar.o diff --git a/arch/powerpc/platforms/powernv/vas-api.c b/arch/powerpc/platforms/powernv/vas-api.c new file mode 100644 index 000..d72755c --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas-api.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * VAS user space API for its accelerators (Only NX-GZIP is supported now) + * Copyright (C) 2019 Haren Myneni, IBM Corp + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "vas.h" + +/* + * The driver creates the device node that can be used as follows: + * For NX-GZIP + * + * fd = open("/dev/crypto/nx-gzip", O_RDWR); + * rc = ioctl(fd, VAS_TX_WIN_OPEN, &attr); + * paste_addr = mmap(NULL, PAGE_SIZE, prot, MAP_SHARED, fd, 0ULL). + * vas_copy(&crb, 0, 1); + * vas_paste(paste_addr, 0, 1); + * close(fd) or exit process to close window. + * + * where "vas_copy" and "vas_paste" are defined in copy-paste.h. + * copy/paste returns to the user space directly. So refer NX hardware + * documententation for excat copy/paste usage and completion / error + * conditions. + */ + +static char*coproc_dev_name = "nx-gzip"; +static atomic_tcoproc_instid = ATOMIC_INIT(0); + +/* + * Wrapper object for the nx-gzip device - there is just one instance of + * this node for the whole system. + */ +struct coproc_dev { + struct cdev cdev; + struct device *device; + char *name; + dev_t devt; + struct class *class; +} coproc_device; + +/* + * One instance per open of a nx-gzip device. Each coproc_instance is + * associated with a VAS window after the caller issues + * VAS_GZIP_TX_WIN_OPEN ioctl. + */ +struct coproc_instance { + int id; + struct vas_window *txwin; +}; + +static char *coproc_devnode(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "crypto/%s", dev_name(dev)); +} + +static int coproc_open(struct inode *inode, struct file *fp) +{ + struct coproc_instance *instance; + + instance = kzalloc(sizeof(*instance), GFP_KERNEL); + if (!instance) + return -ENOMEM; +
[PATCH V2 2/9] powerpc/vas: Define VAS_TX_WIN_OPEN ioctl API
Define the VAS_TX_WIN_OPEN ioctl interface for NX GZIP access from user space. This interface is used to open GZIP send window and mmap region which can be used by userspace to send requests to NX directly with copy/paste instructions. Signed-off-by: Haren Myneni --- Documentation/userspace-api/ioctl/ioctl-number.rst | 1 + arch/powerpc/include/uapi/asm/vas-api.h| 22 ++ 2 files changed, 23 insertions(+) create mode 100644 arch/powerpc/include/uapi/asm/vas-api.h diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index 2e91370..deabc73 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -287,6 +287,7 @@ Code Seq#Include File Comments 'v' 00-1F linux/fs.h conflict! 'v' 00-0F linux/sonypi.h conflict! 'v' 00-0F media/v4l2-subdev.h conflict! +'v' 20-27 arch/powerpc/include/uapi/asm/vas-api.hVAS API 'v' C0-FF linux/meye.hconflict! 'w' allCERN SCI driver 'y' 00-1F packet based user level communications diff --git a/arch/powerpc/include/uapi/asm/vas-api.h b/arch/powerpc/include/uapi/asm/vas-api.h new file mode 100644 index 000..fe95d67 --- /dev/null +++ b/arch/powerpc/include/uapi/asm/vas-api.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright 2019 IBM Corp. + */ + +#ifndef _UAPI_MISC_VAS_H +#define _UAPI_MISC_VAS_H + +#include + +#define VAS_MAGIC 'v' +#define VAS_TX_WIN_OPEN_IOW(VAS_MAGIC, 0x20, struct vas_tx_win_open_attr) + +struct vas_tx_win_open_attr { + __u32 version; + __s16 vas_id; /* specific instance of vas or -1 for default */ + __u16 reserved1; + __u64 flags; /* Future use */ + __u64 reserved2[6]; +}; + +#endif /* _UAPI_MISC_VAS_H */ -- 1.8.3.1
[PATCH V2 1/9] powerpc/vas: Initialize window attributes for GZIP coprocessor type
Initialize send and receive window attributes for GZIP high and normal priority types. Signed-off-by: Haren Myneni --- arch/powerpc/platforms/powernv/vas-window.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 5f9c915..b6572af 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -817,7 +817,8 @@ void vas_init_rx_win_attr(struct vas_rx_win_attr *rxattr, enum vas_cop_type cop) { memset(rxattr, 0, sizeof(*rxattr)); - if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) { + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI || + cop == VAS_COP_TYPE_GZIP || cop == VAS_COP_TYPE_GZIP_HIPRI) { rxattr->pin_win = true; rxattr->nx_win = true; rxattr->fault_win = false; @@ -892,7 +893,8 @@ void vas_init_tx_win_attr(struct vas_tx_win_attr *txattr, enum vas_cop_type cop) { memset(txattr, 0, sizeof(*txattr)); - if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) { + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI || + cop == VAS_COP_TYPE_GZIP || cop == VAS_COP_TYPE_GZIP_HIPRI) { txattr->rej_no_credit = false; txattr->rx_wcred_mode = true; txattr->tx_wcred_mode = true; @@ -976,9 +978,14 @@ static bool tx_win_args_valid(enum vas_cop_type cop, if (attr->wcreds_max > VAS_TX_WCREDS_MAX) return false; - if (attr->user_win && - (cop != VAS_COP_TYPE_FTW || attr->rsvd_txbuf_count)) - return false; + if (attr->user_win) { + if (attr->rsvd_txbuf_count) + return false; + + if (cop != VAS_COP_TYPE_FTW && cop != VAS_COP_TYPE_GZIP && + cop != VAS_COP_TYPE_GZIP_HIPRI) + return false; + } return true; } -- 1.8.3.1
[PATCH V2 0/9] crypto/nx: Enable GZIP engine and provide userpace API
Power9 processor supports Virtual Accelerator Switchboard (VAS) which allows kernel and userspace to send compression requests to Nest Accelerator (NX) directly. The NX unit comprises of 2 842 compression engines and 1 GZIP engine. Linux kernel already has 842 compression support on kernel. This patch series adds GZIP compression support from user space. The GZIP Compression engine implements the ZLIB and GZIP compression algorithms. No plans of adding NX-GZIP compression support in kernel right now. Applications can send requests to NX directly with COPY/PASTE instructions. But kernel has to establish channel / window on NX-GZIP device for the userspace. So userspace access to the GZIP engine is provided through /dev/crypto/nx-gzip device with several operations. An application must open the this device to obtain a file descriptor (fd). Using the fd, application should issue the VAS_TX_WIN_OPEN ioctl to establish a connection to the engine. Once window is opened, should use mmap() system call to map the hardware address of engine's request queue into the application's virtual address space. Then user space forms the request as co-processor Request Block (CRB) and paste this CRB on the mapped HW address using COPY/PASTE instructions. Application can poll on status flags (part of CRB) with timeout for request completion. For VAS_TX_WIN_OPEN ioctl, if user space passes vas_id = -1 (struct vas_tx_win_open_attr), kernel determins the VAS instance on the corresponding chip based on the CPU on which the process is executing. Otherwise, the specified VAS instance is used if application passes the proper VAS instance (vas_id listed in /proc/device-tree/vas@*/ibm,vas_id). Process can open multiple windows with different FDs or can send several requests to NX on the same window at the same time. A userspace library libnxz is available: https://github.com/abalib/power-gzip Applications that use inflate/deflate calls can link with libNXz and use NX GZIP compression without any modification. Tested the available 842 compression on power8 and power9 system to make sure no regression and tested GZIP compression on power9 with tests available in the above link. Thanks to Bulent Abali for nxz library and tests development. Changelog: V2: - Move user space API code to powerpc as suggested. Also this API can be extended to any other coprocessor type that VAS can support in future. Example: Fast thread wakeup feature from VAS - Rebased to 5.6-rc3 Haren Myneni (9): powerpc/vas: Initialize window attributes for GZIP coprocessor type powerpc/vas: Define VAS_TX_WIN_OPEN ioctl API powerpc/vas: Add VAS user space API crypto/nx: Initialize coproc entry with kzalloc crypto/nx: Rename nx-842-powernv file name to nx-common-powernv crypto/NX: Make enable code generic to add new GZIP compression type crypto/nx: Enable and setup GZIP compresstion type crypto/nx: Remove 'pid' in vas_tx_win_attr struct Documentation/powerpc: VAS API Documentation/powerpc/index.rst|1 + Documentation/powerpc/vas-api.rst | 246 + Documentation/userspace-api/ioctl/ioctl-number.rst |1 + arch/powerpc/include/asm/vas.h | 12 +- arch/powerpc/include/uapi/asm/vas-api.h| 22 + arch/powerpc/platforms/powernv/Makefile|2 +- arch/powerpc/platforms/powernv/vas-api.c | 290 + arch/powerpc/platforms/powernv/vas-window.c| 23 +- arch/powerpc/platforms/powernv/vas.h |2 + drivers/crypto/nx/Makefile |2 +- drivers/crypto/nx/nx-842-powernv.c | 1062 -- drivers/crypto/nx/nx-common-powernv.c | 1133 12 files changed, 1723 insertions(+), 1073 deletions(-) create mode 100644 Documentation/powerpc/vas-api.rst create mode 100644 arch/powerpc/include/uapi/asm/vas-api.h create mode 100644 arch/powerpc/platforms/powernv/vas-api.c delete mode 100644 drivers/crypto/nx/nx-842-powernv.c create mode 100644 drivers/crypto/nx/nx-common-powernv.c -- 1.8.3.1
[PATCH v3 8/8] perf/tools/pmu-events/powerpc: Add hv_24x7 socket/chip level metric events
The hv_24×7 feature in IBM® POWER9™ processor-based servers provide the facility to continuously collect large numbers of hardware performance metrics efficiently and accurately. This patch adds hv_24x7 metric file for different Socket/chip resources. Result: power9 platform: command:# ./perf stat --metric-only -M Memory_RD_BW_Chip -C 0 -I 1000 1.96188 0.9 0.3 2.000285720 0.5 0.1 3.000424990 0.4 0.1 command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.979812.32.3 2.0002917132.32.3 3.0004217192.32.3 4.0005509122.32.3 Signed-off-by: Kajol Jain --- .../arch/powerpc/power9/nest_metrics.json | 19 +++ 1 file changed, 19 insertions(+) create mode 100644 tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json new file mode 100644 index ..ac38f5540ac6 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -0,0 +1,19 @@ +[ +{ +"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", +"MetricName": "Memory_RD_BW_Chip", +"MetricGroup": "Memory_BW", +"ScaleUnit": "1.6e-2MB" +}, +{ +"MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", +"MetricName": "Memory_WR_BW_Chip", +"MetricGroup": "Memory_BW", +"ScaleUnit": "1.6e-2MB" +}, +{ +"MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", +"MetricName": "PowerBUS_Frequency", +"ScaleUnit": "2.5e-7GHz" +} +] -- 2.21.0
[PATCH v3 7/8] tools/perf: Enable Hz/hz prinitg for --metric-only option
Commit 54b5091606c18 ("perf stat: Implement --metric-only mode") added function 'valid_only_metric()' which drops "Hz" or "hz", if it is part of "ScaleUnit". This patch enable it since hv_24x7 supports couple of frequency events. Signed-off-by: Kajol Jain --- tools/perf/util/stat-display.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index bc31fccc0057..22dcdfbb9e10 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -236,8 +236,6 @@ static bool valid_only_metric(const char *unit) if (!unit) return false; if (strstr(unit, "/sec") || - strstr(unit, "hz") || - strstr(unit, "Hz") || strstr(unit, "CPUs utilized")) return false; return true; -- 2.21.0
[PATCH v3 6/8] perf/tools: Enhance JSON/metric infrastructure to handle "?"
Patch enhances current metric infrastructure to handle "?" in the metric expression. The "?" can be use for parameters whose value not known while creating metric events and which can be replace later at runtime to the proper value. It also add flexibility to create multiple events out of single metric event added in json file. Patch adds function 'arch_get_runtimeparam' which is a arch specific function, returns the count of metric events need to be created. By default it return 1. One loop is added in function 'metricgroup__add_metric', which create multiple events at run time depend on return value of 'arch_get_runtimeparam' and merge that event in 'group_list'. This infrastructure needed for hv_24x7 socket/chip level events. "hv_24x7" chip level events needs specific chip-id to which the data is requested. Function 'arch_get_runtimeparam' implemented in header.c which extract number of sockets from sysfs file "sockets" under "/sys/devices/hv_24x7/interface/". Signed-off-by: Kajol Jain --- tools/perf/arch/powerpc/util/header.c | 47 +++ tools/perf/util/expr.h| 1 + tools/perf/util/expr.l| 18 - tools/perf/util/expr.y| 2 + tools/perf/util/metricgroup.c | 112 -- tools/perf/util/metricgroup.h | 1 + tools/perf/util/stat-shadow.c | 6 ++ 7 files changed, 144 insertions(+), 43 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 3b4cdfc5efd6..5c15589522fd 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -7,6 +7,11 @@ #include #include #include "header.h" +#include "metricgroup.h" +#include "evlist.h" +#include +#include "pmu.h" +#include #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ @@ -16,6 +21,8 @@ #define PVR_VER(pvr)(((pvr) >> 16) & 0x) /* Version field */ #define PVR_REV(pvr)(((pvr) >> 0) & 0x) /* Revison field */ +#define SOCKETS_INFO_FILE_PATH "/devices/hv_24x7/interface/" + int get_cpuid(char *buffer, size_t sz) { @@ -44,3 +51,43 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } + +int arch_get_runtimeparam(void) +{ + int count = 0; + DIR *dir; + char path[PATH_MAX]; + const char *sysfs = sysfs__mountpoint(); + char filename[] = "sockets"; + FILE *file; + char buf[16], *num; + int data; + + if (!sysfs) + goto out; + + snprintf(path, PATH_MAX, +"%s" SOCKETS_INFO_FILE_PATH, sysfs); + dir = opendir(path); + + if (!dir) + goto out; + + strcat(path, filename); + file = fopen(path, "r"); + + if (!file) + goto out; + + data = fread(buf, 1, sizeof(buf), file); + + if (data == 0) + goto out; + + count = strtol(buf, &num, 10); +out: + if (!count) + count = 1; + + return count; +} diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index 28a0a2dfbd8c..7f7c902bff46 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -15,6 +15,7 @@ struct parse_ctx { struct parse_id ids[MAX_PARSE_ID]; }; +int expr__runtimeparam; void expr__ctx_init(struct parse_ctx *ctx); void expr__add_id(struct parse_ctx *ctx, const char *id, double val); int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr); diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l index 1928f2a3dddc..2cc6fa4b1960 100644 --- a/tools/perf/util/expr.l +++ b/tools/perf/util/expr.l @@ -45,6 +45,20 @@ static char *normalize(char *str) *dst++ = '/'; else if (*str == '\\') *dst++ = *++str; + else if (*str == '?') { + int size = snprintf(NULL, 0, "%d", expr__runtimeparam); + char * paramval = (char *)malloc(size); + int i = 0; + + if(!paramval) + *dst++ = '0'; + else { + sprintf(paramval, "%d", expr__runtimeparam); + while(i < size) + *dst++ = paramval[i++]; + free(paramval); + } + } else *dst++ = *str; str++; @@ -72,8 +86,8 @@ number[0-9]+ sch[-,=] spec \\{sch} -sym[0-9a-zA-Z_\.:@]+ -symbol {spec}*{sym}*{spec}*{sym}* +sym[0-9a-zA-Z_\.:@?]+ +symbol {spec}*{sym}*{spec}*{sym}*{spec}*{sym} %% { diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 4720cbe79357..0f3ef0f37bf4 100644 --- a/tools/perf/util/expr.y
[PATCH v3 5/8] powerpc/hv-24x7: Update post_mobility_fixup() to handle migration
Function 'read_sys_info_pseries()' is added to get system parameter values like number of sockets and chips per socket. and it gets these details via rtas_call with token "PROCESSOR_MODULE_INFO". Incase lpar migrate from one system to another, system parameter details like chips per sockets or number of sockets might change. So, it needs to be re-initialized otherwise, these values corresponds to previous system values. This patch adds a call to 'read_sys_info_pseries()' from 'post-mobility_fixup()' to re-init the physsockets and physchips values. Signed-off-by: Kajol Jain --- arch/powerpc/platforms/pseries/mobility.c | 12 1 file changed, 12 insertions(+) diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index b571285f6c14..226accd6218b 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -371,6 +371,18 @@ void post_mobility_fixup(void) /* Possibly switch to a new RFI flush type */ pseries_setup_rfi_flush(); + /* +* Incase lpar migrate from one system to another, system +* parameter details like chips per sockets and number of sockets +* might change. So, it needs to be re-initialized otherwise these +* values corresponds to previous system. +* Here, adding a call to read_sys_info_pseries() declared in +* platforms/pseries/pseries.h to re-init the physsockets and +* physchips value. +*/ + if (IS_ENABLED(CONFIG_HV_PERF_CTRS) && IS_ENABLED(CONFIG_PPC_RTAS)) + read_sys_info_pseries(); + return; } -- 2.21.0
[PATCH v3 4/8] Documentation/ABI: Add ABI documentation for chips and sockets
Add documentation for the following sysfs files: /sys/devices/hv_24x7/interface/chips, /sys/devices/hv_24x7/interface/sockets Signed-off-by: Kajol Jain --- .../testing/sysfs-bus-event_source-devices-hv_24x7 | 14 ++ 1 file changed, 14 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 index ec27c6c9e737..eb16a3b87ea8 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 @@ -22,6 +22,20 @@ Description: Exposes the "version" field of the 24x7 catalog. This is also extractable from the provided binary "catalog" sysfs entry. +What: /sys/devices/hv_24x7/interface/sockets +Date: February 2020 +Contact: Linux on PowerPC Developer List +Description: read only + This sysfs interface exposes the number of sockets present in the + system. + +What: /sys/devices/hv_24x7/interface/chips +Date: February 2020 +Contact: Linux on PowerPC Developer List +Description: read only + This sysfs interface exposes the number of chips per socket + present in the system. + What: /sys/bus/event_source/devices/hv_24x7/event_descs/ Date: February 2014 Contact: Linux on PowerPC Developer List -- 2.21.0
[PATCH v3 3/8] powerpc/hv-24x7: Add sysfs files inside hv-24x7 device to show processor details
To expose the system dependent parameter like total number of sockets and numbers of chips per socket, patch adds two sysfs files. "sockets" and "chips" are added to /sys/devices/hv_24x7/interface/ of the "hv_24x7" pmu. Signed-off-by: Kajol Jain --- arch/powerpc/perf/hv-24x7.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 9ae00f29bd21..a31bd5b88f7a 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -454,6 +454,20 @@ static ssize_t device_show_string(struct device *dev, return sprintf(buf, "%s\n", (char *)d->var); } +#ifdef CONFIG_PPC_RTAS +static ssize_t sockets_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", physsockets); +} + +static ssize_t chips_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", physchips); +} +#endif + static struct attribute *device_str_attr_create_(char *name, char *str) { struct dev_ext_attribute *attr = kzalloc(sizeof(*attr), GFP_KERNEL); @@ -1100,6 +1114,10 @@ PAGE_0_ATTR(catalog_len, "%lld\n", (unsigned long long)be32_to_cpu(page_0->length) * 4096); static BIN_ATTR_RO(catalog, 0/* real length varies */); static DEVICE_ATTR_RO(domains); +#ifdef CONFIG_PPC_RTAS +static DEVICE_ATTR_RO(sockets); +static DEVICE_ATTR_RO(chips); +#endif static struct bin_attribute *if_bin_attrs[] = { &bin_attr_catalog, @@ -1110,6 +1128,10 @@ static struct attribute *if_attrs[] = { &dev_attr_catalog_len.attr, &dev_attr_catalog_version.attr, &dev_attr_domains.attr, +#ifdef CONFIG_PPC_RTAS + &dev_attr_sockets.attr, + &dev_attr_chips.attr, +#endif NULL, }; -- 2.21.0
[PATCH v3 2/8] powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get processor details
For hv_24x7 socket/chip level events, specific chip-id to which the data requested should be added as part of pmu events. But number of chips/socket in the system details are not exposed. Patch implements read_sys_info_pseries() to get system parameter values like number of sockets and chips per socket. Rtas_call with token "PROCESSOR_MODULE_INFO" is used to get these values. Sub-sequent patch exports these values via sysfs. Patch also make these parameters default to 1. Signed-off-by: Kajol Jain --- arch/powerpc/perf/hv-24x7.c | 72 arch/powerpc/platforms/pseries/pseries.h | 3 + 2 files changed, 75 insertions(+) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 48e8f4b17b91..9ae00f29bd21 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -20,6 +20,11 @@ #include #include +#ifdef CONFIG_PPC_RTAS +#include +#include <../../platforms/pseries/pseries.h> +#endif + #include "hv-24x7.h" #include "hv-24x7-catalog.h" #include "hv-common.h" @@ -57,6 +62,69 @@ static bool is_physical_domain(unsigned domain) } } +#ifdef CONFIG_PPC_RTAS +#define PROCESSOR_MODULE_INFO 43 +#define PROCESSOR_MAX_LENGTH (8 * 1024) + +static int strbe16toh(const char *buf, int offset) +{ + return (buf[offset] << 8) + buf[offset + 1]; +} + +static u32 physsockets;/* Physical sockets */ +static u32 physchips; /* Physical chips */ + +/* + * Function read_sys_info_pseries() make a rtas_call which require + * data buffer of size 8K. As standard 'rtas_data_buf' is of size + * 4K, we are adding new local buffer 'rtas_local_data_buf'. + */ +char rtas_local_data_buf[PROCESSOR_MAX_LENGTH] __cacheline_aligned; + +/* + * read_sys_info_pseries() + * Retrieve the number of sockets and chips per socket details + * through the get-system-parameter rtas call. + */ +void read_sys_info_pseries(void) +{ + int call_status, len, ntypes; + + /* +* Making system parameter: chips and sockets default to 1. +*/ + physsockets = 1; + physchips = 1; + memset(rtas_local_data_buf, 0, PROCESSOR_MAX_LENGTH); + spin_lock(&rtas_data_buf_lock); + + call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, + NULL, + PROCESSOR_MODULE_INFO, + __pa(rtas_local_data_buf), + PROCESSOR_MAX_LENGTH); + + spin_unlock(&rtas_data_buf_lock); + + if (call_status != 0) { + pr_info("%s %s Error calling get-system-parameter (0x%x)\n", + __FILE__, __func__, call_status); + } else { + rtas_local_data_buf[PROCESSOR_MAX_LENGTH - 1] = '\0'; + len = strbe16toh(rtas_local_data_buf, 0); + if (len < 6) + return; + + ntypes = strbe16toh(rtas_local_data_buf, 2); + + if (!ntypes) + return; + physsockets = strbe16toh(rtas_local_data_buf, 4); + physchips = strbe16toh(rtas_local_data_buf, 6); + } +} +#endif /* CONFIG_PPC_RTAS */ + /* Domains for which more than one result element are returned for each event. */ static bool domain_needs_aggregation(unsigned int domain) { @@ -1605,6 +1673,10 @@ static int hv_24x7_init(void) if (r) return r; +#ifdef CONFIG_PPC_RTAS + read_sys_info_pseries(); +#endif + return 0; } diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 13fa370a87e4..1727559ce304 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -19,6 +19,9 @@ extern void request_event_sources_irqs(struct device_node *np, struct pt_regs; extern int pSeries_system_reset_exception(struct pt_regs *regs); +#ifdef CONFIG_PPC_RTAS +extern void read_sys_info_pseries(void); +#endif extern int pSeries_machine_check_exception(struct pt_regs *regs); extern long pseries_machine_check_realmode(struct pt_regs *regs); -- 2.21.0
[PATCH v3 1/8] powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 events run
Commit 2b206ee6b0df ("powerpc/perf/hv-24x7: Display change in counter values")' added to print _change_ in the counter value rather then raw value for 24x7 counters. Incase of transactions, the event count is set to 0 at the beginning of the transaction. It also sets the event's prev_count to the raw value at the time of initialization. Because of setting event count to 0, we are seeing some weird behaviour, whenever we run multiple 24x7 events at a time. For example: command#: ./perf stat -e "{hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/, hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/}" -C 0 -I 1000 sleep 100 1.000121704120 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 1.000121704 5 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 2.000357733 8 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 2.000357733 10 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 3.000495215 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 3.000495215 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 4.000641884 56 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 4.000641884 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 5.000791887 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ Getting these large values in case we do -I. As we are setting event_count to 0, for interval case, overall event_count is not coming in incremental order. As we may can get new delta lesser then previous count. Because of which when we print intervals, we are getting negative value which create these large values. This patch removes part where we set event_count to 0 in function 'h_24x7_event_read'. There won't be much impact as we do set event->hw.prev_count to the raw value at the time of initialization to print change value. With this patch In power9 platform command#: ./perf stat -e "{hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/, hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/}" -C 0 -I 1000 sleep 100 1.000117685 93 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 1.000117685 1 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 2.000349331 98 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 2.000349331 2 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 3.000495900131 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 3.000495900 4 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 4.000645920204 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 4.000645920 61 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 4.284169997 22 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ Signed-off-by: Kajol Jain Suggested-by: Sukadev Bhattiprolu --- arch/powerpc/perf/hv-24x7.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 573e0b309c0c..48e8f4b17b91 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -1400,16 +1400,6 @@ static void h_24x7_event_read(struct perf_event *event) h24x7hw = &get_cpu_var(hv_24x7_hw); h24x7hw->events[i] = event; put_cpu_var(h24x7hw); - /* -* Clear the event count so we can compute the _change_ -* in the 24x7 raw counter value at the end of the txn. -* -* Note that we could alternatively read the 24x7 value -* now and save its value in event->hw.prev_count. But -* that would require issuing a hcall, which would then -* defeat the purpose of using the txn interface. -*/ - local64_set(&event->count, 0); } put_cpu_var(hv_24x7_reqb); -- 2.21.0
[PATCH v3 0/8] powerpc/perf: Add json file metric support for the hv_24x7 socket/chip level events
First patch of the patchset fix inconsistent results we are getting when we run multiple 24x7 events. Patchset adds json file metric support for the hv_24x7 socket/chip level events. "hv_24x7" pmu interface events needs system dependent parameter like socket/chip/core. For example, hv_24x7 chip level events needs specific chip-id to which the data is requested should be added as part of pmu events. So to enable JSON file support to "hv_24x7" interface, patchset expose total number of sockets and chips per-socket details in sysfs files (sockets, chips) under "/sys/devices/hv_24x7/interface/". To get sockets and number of chips per sockets, patchset adds a rtas call with token "PROCESSOR_MODULE_INFO" to get these details. Patchset also handles partition migration case to re-init these system depended parameters by adding proper calls in post_mobility_fixup() (mobility.c). Patch 6 & 8 of the patchset handles perf tool plumbing needed to replace the "?" character in the metric expression to proper value and hv_24x7 json metric file for different Socket/chip resources. Patch set also enable Hz/hz prinitg for --metric-only option to print metric data for bus frequency. Applied and tested all these patches cleanly on top of jiri's flex changes patchset and made required changes. Changelog: v2 -> v3 - Remove setting event_count to 0 part in function 'h_24x7_event_read' with comment rather then adding 0 to event_count value. Suggested by: Sukadev Bhattiprolu - Apply tool side changes require to replace "?" on Jiri's flex patch series and made all require changes to make it compatible with added flex change. v1 -> v2 - Rename hv-24x7 metric json file as nest_metrics.json Kajol Jain (8): powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 events run powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get processor details powerpc/hv-24x7: Add sysfs files inside hv-24x7 device to show processor details Documentation/ABI: Add ABI documentation for chips and sockets powerpc/hv-24x7: Update post_mobility_fixup() to handle migration perf/tools: Enhance JSON/metric infrastructure to handle "?" tools/perf: Enable Hz/hz prinitg for --metric-only option perf/tools/pmu-events/powerpc: Add hv_24x7 socket/chip level metric events .../sysfs-bus-event_source-devices-hv_24x7| 14 +++ arch/powerpc/perf/hv-24x7.c | 104 ++-- arch/powerpc/platforms/pseries/mobility.c | 12 ++ arch/powerpc/platforms/pseries/pseries.h | 3 + tools/perf/arch/powerpc/util/header.c | 47 .../arch/powerpc/power9/nest_metrics.json | 19 +++ tools/perf/util/expr.h| 1 + tools/perf/util/expr.l| 18 ++- tools/perf/util/expr.y| 2 + tools/perf/util/metricgroup.c | 112 +++--- tools/perf/util/metricgroup.h | 1 + tools/perf/util/stat-display.c| 2 - tools/perf/util/stat-shadow.c | 6 + 13 files changed, 286 insertions(+), 55 deletions(-) create mode 100644 tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json -- 2.21.0
[PATCH v3 7/8] tools/perf: Enable Hz/hz prinitg for --metric-only option
Commit 54b5091606c18 ("perf stat: Implement --metric-only mode") added function 'valid_only_metric()' which drops "Hz" or "hz", if it is part of "ScaleUnit". This patch enable it since hv_24x7 supports couple of frequency events. Signed-off-by: Kajol Jain --- tools/perf/util/stat-display.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index bc31fccc0057..22dcdfbb9e10 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -236,8 +236,6 @@ static bool valid_only_metric(const char *unit) if (!unit) return false; if (strstr(unit, "/sec") || - strstr(unit, "hz") || - strstr(unit, "Hz") || strstr(unit, "CPUs utilized")) return false; return true; -- 2.21.0
[PATCH v3 6/8] perf/tools: Enhance JSON/metric infrastructure to handle "?"
Patch enhances current metric infrastructure to handle "?" in the metric expression. The "?" can be use for parameters whose value not known while creating metric events and which can be replace later at runtime to the proper value. It also add flexibility to create multiple events out of single metric event added in json file. Patch adds function 'arch_get_runtimeparam' which is a arch specific function, returns the count of metric events need to be created. By default it return 1. One loop is added in function 'metricgroup__add_metric', which create multiple events at run time depend on return value of 'arch_get_runtimeparam' and merge that event in 'group_list'. This infrastructure needed for hv_24x7 socket/chip level events. "hv_24x7" chip level events needs specific chip-id to which the data is requested. Function 'arch_get_runtimeparam' implemented in header.c which extract number of sockets from sysfs file "sockets" under "/sys/devices/hv_24x7/interface/". Signed-off-by: Kajol Jain --- tools/perf/arch/powerpc/util/header.c | 47 +++ tools/perf/util/expr.h| 1 + tools/perf/util/expr.l| 18 - tools/perf/util/expr.y| 2 + tools/perf/util/metricgroup.c | 112 -- tools/perf/util/metricgroup.h | 1 + tools/perf/util/stat-shadow.c | 6 ++ 7 files changed, 144 insertions(+), 43 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 3b4cdfc5efd6..5c15589522fd 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -7,6 +7,11 @@ #include #include #include "header.h" +#include "metricgroup.h" +#include "evlist.h" +#include +#include "pmu.h" +#include #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ @@ -16,6 +21,8 @@ #define PVR_VER(pvr)(((pvr) >> 16) & 0x) /* Version field */ #define PVR_REV(pvr)(((pvr) >> 0) & 0x) /* Revison field */ +#define SOCKETS_INFO_FILE_PATH "/devices/hv_24x7/interface/" + int get_cpuid(char *buffer, size_t sz) { @@ -44,3 +51,43 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } + +int arch_get_runtimeparam(void) +{ + int count = 0; + DIR *dir; + char path[PATH_MAX]; + const char *sysfs = sysfs__mountpoint(); + char filename[] = "sockets"; + FILE *file; + char buf[16], *num; + int data; + + if (!sysfs) + goto out; + + snprintf(path, PATH_MAX, +"%s" SOCKETS_INFO_FILE_PATH, sysfs); + dir = opendir(path); + + if (!dir) + goto out; + + strcat(path, filename); + file = fopen(path, "r"); + + if (!file) + goto out; + + data = fread(buf, 1, sizeof(buf), file); + + if (data == 0) + goto out; + + count = strtol(buf, &num, 10); +out: + if (!count) + count = 1; + + return count; +} diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index 28a0a2dfbd8c..7f7c902bff46 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -15,6 +15,7 @@ struct parse_ctx { struct parse_id ids[MAX_PARSE_ID]; }; +int expr__runtimeparam; void expr__ctx_init(struct parse_ctx *ctx); void expr__add_id(struct parse_ctx *ctx, const char *id, double val); int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr); diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l index 1928f2a3dddc..2cc6fa4b1960 100644 --- a/tools/perf/util/expr.l +++ b/tools/perf/util/expr.l @@ -45,6 +45,20 @@ static char *normalize(char *str) *dst++ = '/'; else if (*str == '\\') *dst++ = *++str; + else if (*str == '?') { + int size = snprintf(NULL, 0, "%d", expr__runtimeparam); + char * paramval = (char *)malloc(size); + int i = 0; + + if(!paramval) + *dst++ = '0'; + else { + sprintf(paramval, "%d", expr__runtimeparam); + while(i < size) + *dst++ = paramval[i++]; + free(paramval); + } + } else *dst++ = *str; str++; @@ -72,8 +86,8 @@ number[0-9]+ sch[-,=] spec \\{sch} -sym[0-9a-zA-Z_\.:@]+ -symbol {spec}*{sym}*{spec}*{sym}* +sym[0-9a-zA-Z_\.:@?]+ +symbol {spec}*{sym}*{spec}*{sym}*{spec}*{sym} %% { diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 4720cbe79357..0f3ef0f37bf4 100644 --- a/tools/perf/util/expr.y
[PATCH v3 5/8] powerpc/hv-24x7: Update post_mobility_fixup() to handle migration
Function 'read_sys_info_pseries()' is added to get system parameter values like number of sockets and chips per socket. and it gets these details via rtas_call with token "PROCESSOR_MODULE_INFO". Incase lpar migrate from one system to another, system parameter details like chips per sockets or number of sockets might change. So, it needs to be re-initialized otherwise, these values corresponds to previous system values. This patch adds a call to 'read_sys_info_pseries()' from 'post-mobility_fixup()' to re-init the physsockets and physchips values. Signed-off-by: Kajol Jain --- arch/powerpc/platforms/pseries/mobility.c | 12 1 file changed, 12 insertions(+) diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index b571285f6c14..226accd6218b 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -371,6 +371,18 @@ void post_mobility_fixup(void) /* Possibly switch to a new RFI flush type */ pseries_setup_rfi_flush(); + /* +* Incase lpar migrate from one system to another, system +* parameter details like chips per sockets and number of sockets +* might change. So, it needs to be re-initialized otherwise these +* values corresponds to previous system. +* Here, adding a call to read_sys_info_pseries() declared in +* platforms/pseries/pseries.h to re-init the physsockets and +* physchips value. +*/ + if (IS_ENABLED(CONFIG_HV_PERF_CTRS) && IS_ENABLED(CONFIG_PPC_RTAS)) + read_sys_info_pseries(); + return; } -- 2.21.0
[PATCH v3 4/8] Documentation/ABI: Add ABI documentation for chips and sockets
Add documentation for the following sysfs files: /sys/devices/hv_24x7/interface/chips, /sys/devices/hv_24x7/interface/sockets Signed-off-by: Kajol Jain --- .../testing/sysfs-bus-event_source-devices-hv_24x7 | 14 ++ 1 file changed, 14 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 index ec27c6c9e737..eb16a3b87ea8 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 @@ -22,6 +22,20 @@ Description: Exposes the "version" field of the 24x7 catalog. This is also extractable from the provided binary "catalog" sysfs entry. +What: /sys/devices/hv_24x7/interface/sockets +Date: February 2020 +Contact: Linux on PowerPC Developer List +Description: read only + This sysfs interface exposes the number of sockets present in the + system. + +What: /sys/devices/hv_24x7/interface/chips +Date: February 2020 +Contact: Linux on PowerPC Developer List +Description: read only + This sysfs interface exposes the number of chips per socket + present in the system. + What: /sys/bus/event_source/devices/hv_24x7/event_descs/ Date: February 2014 Contact: Linux on PowerPC Developer List -- 2.21.0
[PATCH v3 2/8] powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get processor details
For hv_24x7 socket/chip level events, specific chip-id to which the data requested should be added as part of pmu events. But number of chips/socket in the system details are not exposed. Patch implements read_sys_info_pseries() to get system parameter values like number of sockets and chips per socket. Rtas_call with token "PROCESSOR_MODULE_INFO" is used to get these values. Sub-sequent patch exports these values via sysfs. Patch also make these parameters default to 1. Signed-off-by: Kajol Jain --- arch/powerpc/perf/hv-24x7.c | 72 arch/powerpc/platforms/pseries/pseries.h | 3 + 2 files changed, 75 insertions(+) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 48e8f4b17b91..9ae00f29bd21 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -20,6 +20,11 @@ #include #include +#ifdef CONFIG_PPC_RTAS +#include +#include <../../platforms/pseries/pseries.h> +#endif + #include "hv-24x7.h" #include "hv-24x7-catalog.h" #include "hv-common.h" @@ -57,6 +62,69 @@ static bool is_physical_domain(unsigned domain) } } +#ifdef CONFIG_PPC_RTAS +#define PROCESSOR_MODULE_INFO 43 +#define PROCESSOR_MAX_LENGTH (8 * 1024) + +static int strbe16toh(const char *buf, int offset) +{ + return (buf[offset] << 8) + buf[offset + 1]; +} + +static u32 physsockets;/* Physical sockets */ +static u32 physchips; /* Physical chips */ + +/* + * Function read_sys_info_pseries() make a rtas_call which require + * data buffer of size 8K. As standard 'rtas_data_buf' is of size + * 4K, we are adding new local buffer 'rtas_local_data_buf'. + */ +char rtas_local_data_buf[PROCESSOR_MAX_LENGTH] __cacheline_aligned; + +/* + * read_sys_info_pseries() + * Retrieve the number of sockets and chips per socket details + * through the get-system-parameter rtas call. + */ +void read_sys_info_pseries(void) +{ + int call_status, len, ntypes; + + /* +* Making system parameter: chips and sockets default to 1. +*/ + physsockets = 1; + physchips = 1; + memset(rtas_local_data_buf, 0, PROCESSOR_MAX_LENGTH); + spin_lock(&rtas_data_buf_lock); + + call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, + NULL, + PROCESSOR_MODULE_INFO, + __pa(rtas_local_data_buf), + PROCESSOR_MAX_LENGTH); + + spin_unlock(&rtas_data_buf_lock); + + if (call_status != 0) { + pr_info("%s %s Error calling get-system-parameter (0x%x)\n", + __FILE__, __func__, call_status); + } else { + rtas_local_data_buf[PROCESSOR_MAX_LENGTH - 1] = '\0'; + len = strbe16toh(rtas_local_data_buf, 0); + if (len < 6) + return; + + ntypes = strbe16toh(rtas_local_data_buf, 2); + + if (!ntypes) + return; + physsockets = strbe16toh(rtas_local_data_buf, 4); + physchips = strbe16toh(rtas_local_data_buf, 6); + } +} +#endif /* CONFIG_PPC_RTAS */ + /* Domains for which more than one result element are returned for each event. */ static bool domain_needs_aggregation(unsigned int domain) { @@ -1605,6 +1673,10 @@ static int hv_24x7_init(void) if (r) return r; +#ifdef CONFIG_PPC_RTAS + read_sys_info_pseries(); +#endif + return 0; } diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 13fa370a87e4..1727559ce304 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -19,6 +19,9 @@ extern void request_event_sources_irqs(struct device_node *np, struct pt_regs; extern int pSeries_system_reset_exception(struct pt_regs *regs); +#ifdef CONFIG_PPC_RTAS +extern void read_sys_info_pseries(void); +#endif extern int pSeries_machine_check_exception(struct pt_regs *regs); extern long pseries_machine_check_realmode(struct pt_regs *regs); -- 2.21.0
[PATCH v3 3/8] powerpc/hv-24x7: Add sysfs files inside hv-24x7 device to show processor details
To expose the system dependent parameter like total number of sockets and numbers of chips per socket, patch adds two sysfs files. "sockets" and "chips" are added to /sys/devices/hv_24x7/interface/ of the "hv_24x7" pmu. Signed-off-by: Kajol Jain --- arch/powerpc/perf/hv-24x7.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 9ae00f29bd21..a31bd5b88f7a 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -454,6 +454,20 @@ static ssize_t device_show_string(struct device *dev, return sprintf(buf, "%s\n", (char *)d->var); } +#ifdef CONFIG_PPC_RTAS +static ssize_t sockets_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", physsockets); +} + +static ssize_t chips_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", physchips); +} +#endif + static struct attribute *device_str_attr_create_(char *name, char *str) { struct dev_ext_attribute *attr = kzalloc(sizeof(*attr), GFP_KERNEL); @@ -1100,6 +1114,10 @@ PAGE_0_ATTR(catalog_len, "%lld\n", (unsigned long long)be32_to_cpu(page_0->length) * 4096); static BIN_ATTR_RO(catalog, 0/* real length varies */); static DEVICE_ATTR_RO(domains); +#ifdef CONFIG_PPC_RTAS +static DEVICE_ATTR_RO(sockets); +static DEVICE_ATTR_RO(chips); +#endif static struct bin_attribute *if_bin_attrs[] = { &bin_attr_catalog, @@ -1110,6 +1128,10 @@ static struct attribute *if_attrs[] = { &dev_attr_catalog_len.attr, &dev_attr_catalog_version.attr, &dev_attr_domains.attr, +#ifdef CONFIG_PPC_RTAS + &dev_attr_sockets.attr, + &dev_attr_chips.attr, +#endif NULL, }; -- 2.21.0
[PATCH v3 1/8] powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 events run
Commit 2b206ee6b0df ("powerpc/perf/hv-24x7: Display change in counter values")' added to print _change_ in the counter value rather then raw value for 24x7 counters. Incase of transactions, the event count is set to 0 at the beginning of the transaction. It also sets the event's prev_count to the raw value at the time of initialization. Because of setting event count to 0, we are seeing some weird behaviour, whenever we run multiple 24x7 events at a time. For example: command#: ./perf stat -e "{hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/, hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/}" -C 0 -I 1000 sleep 100 1.000121704120 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 1.000121704 5 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 2.000357733 8 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 2.000357733 10 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 3.000495215 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 3.000495215 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 4.000641884 56 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 4.000641884 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 5.000791887 18,446,744,073,709,551,616 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ Getting these large values in case we do -I. As we are setting event_count to 0, for interval case, overall event_count is not coming in incremental order. As we may can get new delta lesser then previous count. Because of which when we print intervals, we are getting negative value which create these large values. This patch removes part where we set event_count to 0 in function 'h_24x7_event_read'. There won't be much impact as we do set event->hw.prev_count to the raw value at the time of initialization to print change value. With this patch In power9 platform command#: ./perf stat -e "{hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/, hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/}" -C 0 -I 1000 sleep 100 1.000117685 93 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 1.000117685 1 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 2.000349331 98 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 2.000349331 2 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 3.000495900131 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 3.000495900 4 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 4.000645920204 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ 4.000645920 61 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=1/ 4.284169997 22 hv_24x7/PM_MCS01_128B_RD_DISP_PORT01,chip=0/ Signed-off-by: Kajol Jain Suggested-by: Sukadev Bhattiprolu --- arch/powerpc/perf/hv-24x7.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 573e0b309c0c..48e8f4b17b91 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -1400,16 +1400,6 @@ static void h_24x7_event_read(struct perf_event *event) h24x7hw = &get_cpu_var(hv_24x7_hw); h24x7hw->events[i] = event; put_cpu_var(h24x7hw); - /* -* Clear the event count so we can compute the _change_ -* in the 24x7 raw counter value at the end of the txn. -* -* Note that we could alternatively read the 24x7 value -* now and save its value in event->hw.prev_count. But -* that would require issuing a hcall, which would then -* defeat the purpose of using the txn interface. -*/ - local64_set(&event->count, 0); } put_cpu_var(hv_24x7_reqb); -- 2.21.0
[PATCH v3 0/8] powerpc/perf: Add json file metric support for the hv_24x7 socket/chip level events
First patch of the patchset fix inconsistent results we are getting when we run multiple 24x7 events. Patchset adds json file metric support for the hv_24x7 socket/chip level events. "hv_24x7" pmu interface events needs system dependent parameter like socket/chip/core. For example, hv_24x7 chip level events needs specific chip-id to which the data is requested should be added as part of pmu events. So to enable JSON file support to "hv_24x7" interface, patchset expose total number of sockets and chips per-socket details in sysfs files (sockets, chips) under "/sys/devices/hv_24x7/interface/". To get sockets and number of chips per sockets, patchset adds a rtas call with token "PROCESSOR_MODULE_INFO" to get these details. Patchset also handles partition migration case to re-init these system depended parameters by adding proper calls in post_mobility_fixup() (mobility.c). Patch 6 & 8 of the patchset handles perf tool plumbing needed to replace the "?" character in the metric expression to proper value and hv_24x7 json metric file for different Socket/chip resources. Patch set also enable Hz/hz prinitg for --metric-only option to print metric data for bus frequency. Applied and tested all these patches cleanly on top of jiri's flex changes patchset and made required changes. Changelog: v2 -> v3 - Remove setting event_count to 0 part in function 'h_24x7_event_read' with comment rather then adding 0 to event_count value. Suggested by: Sukadev Bhattiprolu - Apply tool side changes require to replace "?" on Jiri's flex patch series and made all require changes to make it compatible with added flex change. v1 -> v2 - Rename hv-24x7 metric json file as nest_metrics.json Kajol Jain (8): powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 events run powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get processor details powerpc/hv-24x7: Add sysfs files inside hv-24x7 device to show processor details Documentation/ABI: Add ABI documentation for chips and sockets powerpc/hv-24x7: Update post_mobility_fixup() to handle migration perf/tools: Enhance JSON/metric infrastructure to handle "?" tools/perf: Enable Hz/hz prinitg for --metric-only option perf/tools/pmu-events/powerpc: Add hv_24x7 socket/chip level metric events .../sysfs-bus-event_source-devices-hv_24x7| 14 +++ arch/powerpc/perf/hv-24x7.c | 104 ++-- arch/powerpc/platforms/pseries/mobility.c | 12 ++ arch/powerpc/platforms/pseries/pseries.h | 3 + tools/perf/arch/powerpc/util/header.c | 47 .../arch/powerpc/power9/nest_metrics.json | 19 +++ tools/perf/util/expr.h| 1 + tools/perf/util/expr.l| 18 ++- tools/perf/util/expr.y| 2 + tools/perf/util/metricgroup.c | 112 +++--- tools/perf/util/metricgroup.h | 1 + tools/perf/util/stat-display.c| 2 - tools/perf/util/stat-shadow.c | 6 + 13 files changed, 286 insertions(+), 55 deletions(-) create mode 100644 tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json -- 2.21.0
Re: [RFC PATCH v1] powerpc/prom_init: disable XIVE in Secure VM.
On 2/29/20 8:54 AM, Ram Pai wrote: > XIVE is not correctly enabled for Secure VM in the KVM Hypervisor yet. > > Hence Secure VM, must always default to XICS interrupt controller. have you tried XIVE emulation 'kernel-irqchip=off' ? > If XIVE is requested through kernel command line option "xive=on", > override and turn it off. This is incorrect. It is negotiated through CAS depending on the FW capabilities and the KVM capabilities. > If XIVE is the only supported platform interrupt controller; specified > through qemu option "ic-mode=xive", simply abort. Otherwise default to > XICS. I don't think it is a good approach to downgrade the guest kernel capabilities this way. PAPR has specified the CAS negotiation process for this purpose. It comes in two parts under KVM. First the KVM hypervisor advertises or not a capability to QEMU. The second is the CAS negotiation process between QEMU and the guest OS. The SVM specifications might not be complete yet and if some features are incompatible, I think we should modify the capabilities advertised by the hypervisor : no XIVE in case of SVM. QEMU will automatically use the fallback path and emulate the XIVE device, same as setting 'kernel-irqchip=off'. This is how KVM operates on Boston systems today which do not have the right level of FW to support migration. XIVE is emulated. It will give SVM a working default without any changes in QEMU or the guest. Now, if one needs more performance, accelerated xics should be activated on the command line with 'xive=off'. I understand that SVM requires FW support. Do we have a SVM capability returned to QEMU ? That might have been addressed in other patches. Thanks, C. > > Cc: kvm-...@vger.kernel.org > Cc: linuxppc-dev@lists.ozlabs.org > Cc: Michael Ellerman > Cc: Thiago Jung Bauermann > Cc: Michael Anderson > Cc: Sukadev Bhattiprolu > Cc: Alexey Kardashevskiy > Cc: Paul Mackerras > Cc: Greg Kurz > Cc: Cedric Le Goater > Cc: David Gibson > Signed-off-by: Ram Pai > --- > arch/powerpc/kernel/prom_init.c | 43 > - > 1 file changed, 30 insertions(+), 13 deletions(-) > > diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c > index 5773453..dd96c82 100644 > --- a/arch/powerpc/kernel/prom_init.c > +++ b/arch/powerpc/kernel/prom_init.c > @@ -805,6 +805,18 @@ static void __init early_cmdline_parse(void) > #endif > } > > +#ifdef CONFIG_PPC_SVM > + opt = prom_strstr(prom_cmd_line, "svm="); > + if (opt) { > + bool val; > + > + opt += sizeof("svm=") - 1; > + if (!prom_strtobool(opt, &val)) > + prom_svm_enable = val; > + prom_printf("svm =%d\n", prom_svm_enable); > + } > +#endif /* CONFIG_PPC_SVM */ > + > #ifdef CONFIG_PPC_PSERIES > prom_radix_disable = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT); > opt = prom_strstr(prom_cmd_line, "disable_radix"); > @@ -823,23 +835,22 @@ static void __init early_cmdline_parse(void) > if (prom_radix_disable) > prom_debug("Radix disabled from cmdline\n"); > > - opt = prom_strstr(prom_cmd_line, "xive=off"); > - if (opt) { > +#ifdef CONFIG_PPC_SVM > + if (prom_svm_enable) { > prom_xive_disable = true; > - prom_debug("XIVE disabled from cmdline\n"); > + prom_debug("XIVE disabled in Secure VM\n"); > } > -#endif /* CONFIG_PPC_PSERIES */ > - > -#ifdef CONFIG_PPC_SVM > - opt = prom_strstr(prom_cmd_line, "svm="); > - if (opt) { > - bool val; > +#endif /* CONFIG_PPC_SVM */ > > - opt += sizeof("svm=") - 1; > - if (!prom_strtobool(opt, &val)) > - prom_svm_enable = val; > + if (!prom_xive_disable) { > + opt = prom_strstr(prom_cmd_line, "xive=off"); > + if (opt) { > + prom_xive_disable = true; > + prom_debug("XIVE disabled from cmdline\n"); > + } > } > -#endif /* CONFIG_PPC_SVM */ > + > +#endif /* CONFIG_PPC_PSERIES */ > } > > #ifdef CONFIG_PPC_PSERIES > @@ -1251,6 +1262,12 @@ static void __init prom_parse_xive_model(u8 val, > break; > case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */ > prom_debug("XIVE - exploitation mode supported\n"); > + > +#ifdef CONFIG_PPC_SVM > + if (prom_svm_enable) > + prom_panic("WARNING: xive unsupported in Secure VM\n"); > +#endif /* CONFIG_PPC_SVM */ > + > if (prom_xive_disable) { > /* >* If we __have__ to do XIVE, we're better off ignoring >