[RESEND PATCH v3 07/20] mtd: spi_nor: Move manufacturer quad_enable() in ->default_init()
From: Tudor Ambarus The goal is to move the quad_enable manufacturer specific init in the nor->manufacturer->fixups->default_init() The legacy quad_enable() implementation is spansion_quad_enable(), select this method by default. Set specific manufacturer fixups->default_init() hooks to overwrite the default quad_enable() implementation when needed. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: collect R-b drivers/mtd/spi-nor/spi-nor.c | 48 ++- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 3dbbfe34d1d2..2a239531704a 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4150,13 +4150,38 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } +static void macronix_set_default_init(struct spi_nor *nor) +{ + nor->params.quad_enable = macronix_quad_enable; +} + +static void st_micron_set_default_init(struct spi_nor *nor) +{ + nor->params.quad_enable = NULL; +} + /** * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and - * settings based on ->default_init() hook. + * settings based on MFR register and ->default_init() hook. * @nor: pointer to a 'struct spi-nor'. */ static void spi_nor_manufacturer_init_params(struct spi_nor *nor) { + /* Init flash parameters based on MFR */ + switch (JEDEC_MFR(nor->info)) { + case SNOR_MFR_MACRONIX: + macronix_set_default_init(nor); + break; + + case SNOR_MFR_ST: + case SNOR_MFR_MICRON: + st_micron_set_default_init(nor); + break; + + default: + break; + } + if (nor->info->fixups && nor->info->fixups->default_init) nor->info->fixups->default_init(nor); } @@ -4168,6 +4193,9 @@ static int spi_nor_init_params(struct spi_nor *nor) const struct flash_info *info = nor->info; u8 i, erase_mask; + /* Initialize legacy flash parameters and settings. */ + params->quad_enable = spansion_quad_enable; + /* Set SPI NOR sizes. */ params->size = (u64)info->sector_size * info->n_sectors; params->page_size = info->page_size; @@ -4233,24 +4261,6 @@ static int spi_nor_init_params(struct spi_nor *nor) SPINOR_OP_SE); spi_nor_init_uniform_erase_map(map, erase_mask, params->size); - /* Select the procedure to set the Quad Enable bit. */ - if (params->hwcaps.mask & (SNOR_HWCAPS_READ_QUAD | - SNOR_HWCAPS_PP_QUAD)) { - switch (JEDEC_MFR(info)) { - case SNOR_MFR_MACRONIX: - params->quad_enable = macronix_quad_enable; - break; - - case SNOR_MFR_ST: - case SNOR_MFR_MICRON: - break; - - default: - /* Kept only for backward compatibility purpose. */ - params->quad_enable = spansion_quad_enable; - break; - } - } spi_nor_manufacturer_init_params(nor); -- 2.9.5
[RESEND PATCH v3 14/20] mtd: spi_nor: Add a ->setup() method
From: Tudor Ambarus nor->params.setup() configures the SPI NOR memory. Useful for SPI NOR flashes that have peculiarities to the SPI NOR standard, e.g. different opcodes, specific address calculation, page size, etc. Right now the only user will be the S3AN chips, but other manufacturers can implement it if needed. Move spi_nor_setup() related code in order to avoid a forward declaration to spi_nor_default_setup(). Reviewed-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: collect R-b, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 432 +- include/linux/mtd/spi-nor.h | 5 + 2 files changed, 226 insertions(+), 211 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b96a7066a36c..2aca56e07341 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4144,6 +4144,226 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } +static int spi_nor_select_read(struct spi_nor *nor, + u32 shared_hwcaps) +{ + int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_READ_MASK) - 1; + const struct spi_nor_read_command *read; + + if (best_match < 0) + return -EINVAL; + + cmd = spi_nor_hwcaps_read2cmd(BIT(best_match)); + if (cmd < 0) + return -EINVAL; + + read = >params.reads[cmd]; + nor->read_opcode = read->opcode; + nor->read_proto = read->proto; + + /* +* In the spi-nor framework, we don't need to make the difference +* between mode clock cycles and wait state clock cycles. +* Indeed, the value of the mode clock cycles is used by a QSPI +* flash memory to know whether it should enter or leave its 0-4-4 +* (Continuous Read / XIP) mode. +* eXecution In Place is out of the scope of the mtd sub-system. +* Hence we choose to merge both mode and wait state clock cycles +* into the so called dummy clock cycles. +*/ + nor->read_dummy = read->num_mode_clocks + read->num_wait_states; + return 0; +} + +static int spi_nor_select_pp(struct spi_nor *nor, +u32 shared_hwcaps) +{ + int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_PP_MASK) - 1; + const struct spi_nor_pp_command *pp; + + if (best_match < 0) + return -EINVAL; + + cmd = spi_nor_hwcaps_pp2cmd(BIT(best_match)); + if (cmd < 0) + return -EINVAL; + + pp = >params.page_programs[cmd]; + nor->program_opcode = pp->opcode; + nor->write_proto = pp->proto; + return 0; +} + +/** + * spi_nor_select_uniform_erase() - select optimum uniform erase type + * @map: the erase map of the SPI NOR + * @wanted_size: the erase type size to search for. Contains the value of + * info->sector_size or of the "small sector" size in case + * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined. + * + * Once the optimum uniform sector erase command is found, disable all the + * other. + * + * Return: pointer to erase type on success, NULL otherwise. + */ +static const struct spi_nor_erase_type * +spi_nor_select_uniform_erase(struct spi_nor_erase_map *map, +const u32 wanted_size) +{ + const struct spi_nor_erase_type *tested_erase, *erase = NULL; + int i; + u8 uniform_erase_type = map->uniform_erase_type; + + for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { + if (!(uniform_erase_type & BIT(i))) + continue; + + tested_erase = >erase_type[i]; + + /* +* If the current erase size is the one, stop here: +* we have found the right uniform Sector Erase command. +*/ + if (tested_erase->size == wanted_size) { + erase = tested_erase; + break; + } + + /* +* Otherwise, the current erase size is still a valid canditate. +* Select the biggest valid candidate. +*/ + if (!erase && tested_erase->size) + erase = tested_erase; + /* keep iterating to find the wanted_size */ + } + + if (!erase) + return NULL; + + /* Disable all other Sector Erase commands. */ + map->uniform_erase_type &= ~SNOR_ERASE_TYPE_MASK; + map->uniform_erase_type |= BIT(erase - map->erase_type); + return erase; +} + +static int spi_nor_select_erase(struct spi_nor *nor, u32 wanted_size) +{ + struct spi_nor_erase_map *map = >params.erase_map; + const struct spi_nor_erase_type *erase = NULL; + struct mtd_info *mtd = >mtd; + int i; + + /* +* The previous implementation handling Sector Erase commands assumed +
[RESEND PATCH v3 13/20] mtd: spi-nor: Add a ->convert_addr() method
From: Boris Brezillon In order to separate manufacturer quirks from the core we need to get rid of all the manufacturer specific flags, like the SNOR_F_S3AN_ADDR_DEFAULT one. This can easily be replaced by a ->convert_addr() hook, which when implemented will provide the core with an easy way to convert an absolute address into something the flash understands. Right now the only user are the S3AN chips, but other manufacturers can implement it if needed. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 24 ++-- include/linux/mtd/spi-nor.h | 17 ++--- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index c862a59ce9df..b96a7066a36c 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -899,10 +899,9 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) * Addr can safely be unsigned int, the biggest S3AN device is smaller than * 4 MiB. */ -static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) +static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) { - unsigned int offset; - unsigned int page; + u32 offset, page; offset = addr % nor->page_size; page = addr / nor->page_size; @@ -911,6 +910,14 @@ static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) return page | offset; } +static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr) +{ + if (!nor->params.convert_addr) + return addr; + + return nor->params.convert_addr(nor, addr); +} + /* * Initiate the erasure of a single sector */ @@ -918,8 +925,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) { int i; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); if (nor->erase) return nor->erase(nor, addr); @@ -2535,8 +2541,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, while (len) { loff_t addr = from; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); ret = spi_nor_read_data(nor, addr, len, buf); if (ret == 0) { @@ -2680,8 +2685,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, page_remain = min_t(size_t, nor->page_size - page_offset, len - i); - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); write_enable(nor); ret = spi_nor_write_data(nor, addr, page_remain, buf + i); @@ -2748,7 +2752,7 @@ static int s3an_nor_scan(struct spi_nor *nor) nor->mtd.erasesize = 8 * nor->page_size; } else { /* Flash in Default addressing mode */ - nor->flags |= SNOR_F_S3AN_ADDR_DEFAULT; + nor->params.convert_addr = s3an_convert_addr; } return 0; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index ea3bcac54dc2..35aad92a4ff8 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -237,13 +237,12 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB= BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), - SNOR_F_READY_XSR_RDY= BIT(4), - SNOR_F_USE_CLSR = BIT(5), - SNOR_F_BROKEN_RESET = BIT(6), - SNOR_F_4B_OPCODES = BIT(7), - SNOR_F_HAS_4BAIT= BIT(8), - SNOR_F_HAS_LOCK = BIT(9), + SNOR_F_READY_XSR_RDY= BIT(3), + SNOR_F_USE_CLSR = BIT(4), + SNOR_F_BROKEN_RESET = BIT(5), + SNOR_F_4B_OPCODES = BIT(6), + SNOR_F_HAS_4BAIT= BIT(7), + SNOR_F_HAS_LOCK = BIT(8), }; /** @@ -496,6 +495,9 @@ struct spi_nor_locking_ops { * Table. * @quad_enable: enables SPI NOR quad mode. * @set_4byte: puts the SPI NOR in 4 byte addressing mode. + * @convert_addr: converts an absolute address into something the flash + * will understand. Particularly useful when pagesize is + * not a power-of-2. * @locking_ops: SPI NOR locking methods. */ struct spi_nor_flash_parameter { @@ -510,6 +512,7 @@ struct spi_nor_flash_parameter { int (*quad_enable)(struct spi_nor *nor); int (*set_4byte)(struct spi_nor *nor,
[RESEND PATCH v3 10/20] mtd: spi-nor: Rework the SPI NOR lock/unlock logic
From: Boris Brezillon Add the SNOR_F_HAS_LOCK flag and set it when SPI_NOR_HAS_LOCK is set in the flash_info entry or when it's a Micron or ST flash. Move the locking hooks in a separate struct so that we have just one field to update when we change the locking implementation. Signed-off-by: Boris Brezillon [tudor.amba...@microchip.com: use ->default_init() hook, introduce spi_nor_late_init_params(), set ops in nor->params] Signed-off-by: Tudor Ambarus --- v3: no changes, clear_sr_bp() is handled in the last patch of the series. drivers/mtd/spi-nor/spi-nor.c | 50 --- include/linux/mtd/spi-nor.h | 23 ++-- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 235e82a121a1..3f997797fa9d 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1598,6 +1598,12 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) return stm_is_locked_sr(nor, ofs, len, status); } +static const struct spi_nor_locking_ops stm_locking_ops = { + .lock = stm_lock, + .unlock = stm_unlock, + .is_locked = stm_is_locked, +}; + static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct spi_nor *nor = mtd_to_spi_nor(mtd); @@ -1607,7 +1613,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_lock(nor, ofs, len); + ret = nor->params.locking_ops->lock(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); return ret; @@ -1622,7 +1628,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_unlock(nor, ofs, len); + ret = nor->params.locking_ops->unlock(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); return ret; @@ -1637,7 +1643,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_is_locked(nor, ofs, len); + ret = nor->params.locking_ops->is_locked(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); return ret; @@ -4148,6 +4154,7 @@ static void macronix_set_default_init(struct spi_nor *nor) static void st_micron_set_default_init(struct spi_nor *nor) { + nor->flags = SNOR_F_HAS_LOCK; nor->params.quad_enable = NULL; nor->params.set_4byte = st_micron_set_4byte; } @@ -4292,6 +4299,23 @@ static void spi_nor_info_init_params(struct spi_nor *nor) } /** + * spi_nor_late_init_params() - Late initialization of default flash parameters. + * @nor: pointer to a 'struct spi_nor' + * + * Used to set default flash parameters and settings when the ->default_init() + * hook or the SFDP parser let voids. + */ +static void spi_nor_late_init_params(struct spi_nor *nor) +{ + /* +* NOR protection support. When locking_ops are not provided, we pick +* the default ones. +*/ + if (nor->flags & SNOR_F_HAS_LOCK && !nor->params.locking_ops) + nor->params.locking_ops = _locking_ops; +} + +/** * spi_nor_init_params() - Initialize the flash's parameters and settings. * @nor: pointer to a 'struct spi-nor'. * @@ -4316,6 +4340,10 @@ static void spi_nor_info_init_params(struct spi_nor *nor) *Please not that there is a ->post_bfpt() fixup hook that can overwrite the *flash parameters and settings imediately after parsing the Basic Flash *Parameter Table. + * + * 4/ Late default flash parameters initialization, used when the + * ->default_init() hook or the SFDP parser do not set specific params. + * spi_nor_late_init_params() */ static void spi_nor_init_params(struct spi_nor *nor) { @@ -4326,6 +4354,8 @@ static void spi_nor_init_params(struct spi_nor *nor) if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && !(nor->info->flags & SPI_NOR_SKIP_SFDP)) spi_nor_sfdp_init_params(nor); + + spi_nor_late_init_params(nor); } static int spi_nor_select_read(struct spi_nor *nor, @@ -4707,6 +4737,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (info->flags & SPI_S3AN) nor->flags |= SNOR_F_READY_XSR_RDY; + if (info->flags & SPI_NOR_HAS_LOCK) + nor->flags |= SNOR_F_HAS_LOCK; + /* * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up * with the software protection bits set. @@ -4731,16 +4764,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, mtd->_read = spi_nor_read; mtd->_resume = spi_nor_resume; - /* NOR protection support for STmicro/Micron chips and similar */ - if (JEDEC_MFR(info) == SNOR_MFR_ST || -
[RESEND PATCH v3 18/20] mtd: spi_nor: Introduce spi_nor_set_addr_width()
From: Tudor Ambarus Parsing of flash parameters were interleaved with setting of the nor addr width. Dedicate a function for setting nor addr width. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: no changes drivers/mtd/spi-nor/spi-nor.c | 50 ++- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index dcda96a20f6c..d13317d1f372 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4739,6 +4739,33 @@ static const struct flash_info *spi_nor_match_id(const char *name) return NULL; } +static int spi_nor_set_addr_width(struct spi_nor *nor) +{ + if (nor->addr_width) { + /* already configured from SFDP */ + } else if (nor->info->addr_width) { + nor->addr_width = nor->info->addr_width; + } else if (nor->mtd.size > 0x100) { + /* enable 4-byte addressing if the device exceeds 16MiB */ + nor->addr_width = 4; + } else { + nor->addr_width = 3; + } + + if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { + dev_err(nor->dev, "address width is too large: %u\n", + nor->addr_width); + return -EINVAL; + } + + /* Set 4byte opcodes when possible. */ + if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES && + !(nor->flags & SNOR_F_HAS_4BAIT)) + spi_nor_set_4byte_opcodes(nor); + + return 0; +} + int spi_nor_scan(struct spi_nor *nor, const char *name, const struct spi_nor_hwcaps *hwcaps) { @@ -4885,29 +4912,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (ret) return ret; - if (nor->addr_width) { - /* already configured from SFDP */ - } else if (info->addr_width) { - nor->addr_width = info->addr_width; - } else if (mtd->size > 0x100) { - /* enable 4-byte addressing if the device exceeds 16MiB */ - nor->addr_width = 4; - } else { - nor->addr_width = 3; - } - if (info->flags & SPI_NOR_4B_OPCODES) nor->flags |= SNOR_F_4B_OPCODES; - if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES && - !(nor->flags & SNOR_F_HAS_4BAIT)) - spi_nor_set_4byte_opcodes(nor); - - if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { - dev_err(dev, "address width is too large: %u\n", - nor->addr_width); - return -EINVAL; - } + ret = spi_nor_set_addr_width(nor); + if (ret) + return ret; /* Send all the required SPI flash commands to initialize device */ ret = spi_nor_init(nor); -- 2.9.5
[RESEND PATCH v3 16/20] mtd: spi-nor: Add the SPI_NOR_XSR_RDY flag
From: Boris Brezillon S3AN flashes use a specific opcode to read the status register. We currently use the SPI_S3AN flag to decide whether this specific SR read opcode should be used, but SPI_S3AN is about to disappear, so let's add a new flag. Note that we use the same bit as SPI_S3AN implies SPI_NOR_XSR_RDY and vice versa. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes drivers/mtd/spi-nor/spi-nor.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index edf1c8badac9..2699e999d21a 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -211,6 +211,14 @@ struct flash_info { * bit. Must be used with * SPI_NOR_HAS_LOCK. */ +#define SPI_NOR_XSR_RDYBIT(10) /* +* S3AN flashes have specific opcode to +* read the status register. +* Flags SPI_NOR_XSR_RDY and SPI_S3AN +* use the same bit as one implies the +* other, but we will get rid of +* SPI_S3AN soon. +*/ #defineSPI_S3ANBIT(10) /* * Xilinx Spartan 3AN In-System Flash * (MFR cannot be used for probing @@ -4798,7 +4806,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, * spi_nor_wait_till_ready(). Xilinx S3AN share MFR * with Atmel spi-nor */ - if (info->flags & SPI_S3AN) + if (info->flags & SPI_NOR_XSR_RDY) nor->flags |= SNOR_F_READY_XSR_RDY; if (info->flags & SPI_NOR_HAS_LOCK) -- 2.9.5
[RESEND PATCH v3 11/20] mtd: spi-nor: Add post_sfdp() hook to tweak flash config
From: Boris Brezillon SFDP tables are sometimes wrong and we need a way to override the config chosen by the SFDP parsing logic without discarding all of it. Add a new hook called after the SFDP parsing has taken place to deal with such problems. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 33 - 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 3f997797fa9d..b8caf5171ff5 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -158,6 +158,11 @@ struct sfdp_bfpt { *flash parameters when information provided by the flash_info *table is incomplete or wrong. * @post_bfpt: called after the BFPT table has been parsed + * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs + * that do not support RDSFDP). Typically used to tweak various + * parameters that could not be extracted by other means (i.e. + * when information provided by the SFDP/flash_info tables are + * incomplete or wrong). * * Those hooks can be used to tweak the SPI NOR configuration when the SFDP * table is broken or not available. @@ -168,6 +173,7 @@ struct spi_nor_fixups { const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt, struct spi_nor_flash_parameter *params); + void (*post_sfdp)(struct spi_nor *nor); }; struct flash_info { @@ -4299,6 +4305,22 @@ static void spi_nor_info_init_params(struct spi_nor *nor) } /** + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings + * after SFDP has been parsed (is also called for SPI NORs that do not + * support RDSFDP). + * @nor: pointer to a 'struct spi_nor' + * + * Typically used to tweak various parameters that could not be extracted by + * other means (i.e. when information provided by the SFDP/flash_info tables + * are incomplete or wrong). + */ +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor) +{ + if (nor->info->fixups && nor->info->fixups->post_sfdp) + nor->info->fixups->post_sfdp(nor); +} + +/** * spi_nor_late_init_params() - Late initialization of default flash parameters. * @nor: pointer to a 'struct spi_nor' * @@ -4341,7 +4363,14 @@ static void spi_nor_late_init_params(struct spi_nor *nor) *flash parameters and settings imediately after parsing the Basic Flash *Parameter Table. * - * 4/ Late default flash parameters initialization, used when the + * which can be overwritten by: + * 4/ Post SFDP flash parameters initialization. Used to tweak various + *parameters that could not be extracted by other means (i.e. when + *information provided by the SFDP/flash_info tables are incomplete or + *wrong). + * spi_nor_post_sfdp_fixups() + * + * 5/ Late default flash parameters initialization, used when the * ->default_init() hook or the SFDP parser do not set specific params. * spi_nor_late_init_params() */ @@ -4355,6 +4384,8 @@ static void spi_nor_init_params(struct spi_nor *nor) !(nor->info->flags & SPI_NOR_SKIP_SFDP)) spi_nor_sfdp_init_params(nor); + spi_nor_post_sfdp_fixups(nor); + spi_nor_late_init_params(nor); } -- 2.9.5
[RESEND PATCH v3 08/20] mtd: spi-nor: Split spi_nor_init_params()
From: Tudor Ambarus Add functions to delimit what the chunks of code do: static void spi_nor_init_params() { spi_nor_info_init_params() spi_nor_manufacturer_init_params() spi_nor_sfdp_init_params() } Add descriptions to all methods. spi_nor_init_params() becomes of type void, as all its children return void. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: rename spi_nor_legacy_init_params() to spi_nor_info_init_params() drivers/mtd/spi-nor/spi-nor.c | 83 --- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 2a239531704a..1e7f8dc3457d 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4186,7 +4186,34 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor) nor->info->fixups->default_init(nor); } -static int spi_nor_init_params(struct spi_nor *nor) +/** + * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings + * based on JESD216 SFDP standard. + * @nor: pointer to a 'struct spi-nor'. + * + * The method has a roll-back mechanism: in case the SFDP parsing fails, the + * legacy flash parameters and settings will be restored. + */ +static void spi_nor_sfdp_init_params(struct spi_nor *nor) +{ + struct spi_nor_flash_parameter sfdp_params; + + memcpy(_params, >params, sizeof(sfdp_params)); + + if (spi_nor_parse_sfdp(nor, _params)) { + nor->addr_width = 0; + nor->flags &= ~SNOR_F_4B_OPCODES; + } else { + memcpy(>params, _params, sizeof(nor->params)); + } +} + +/** + * spi_nor_info_init_params() - Initialize the flash's parameters and settings + * based on nor->info data. + * @nor: pointer to a 'struct spi-nor'. + */ +static void spi_nor_info_init_params(struct spi_nor *nor) { struct spi_nor_flash_parameter *params = >params; struct spi_nor_erase_map *map = >erase_map; @@ -4260,25 +4287,43 @@ static int spi_nor_init_params(struct spi_nor *nor) spi_nor_set_erase_type(>erase_type[i], info->sector_size, SPINOR_OP_SE); spi_nor_init_uniform_erase_map(map, erase_mask, params->size); +} +/** + * spi_nor_init_params() - Initialize the flash's parameters and settings. + * @nor: pointer to a 'struct spi-nor'. + * + * The flash parameters and settings are initialized based on a sequence of + * calls that are ordered by priority: + * + * 1/ Default flash parameters initialization. The initializations are done + *based on nor->info data: + * spi_nor_info_init_params() + * + * which can be overwritten by: + * 2/ Manufacturer flash parameters initialization. The initializations are + *done based on MFR register, or when the decisions can not be done solely + *based on MFR, by using specific flash_info tweeks, ->default_init(): + * spi_nor_manufacturer_init_params() + * + * which can be overwritten by: + * 3/ SFDP flash parameters initialization. JESD216 SFDP is a standard and + *should be more accurate that the above. + * spi_nor_sfdp_init_params() + * + *Please not that there is a ->post_bfpt() fixup hook that can overwrite the + *flash parameters and settings imediately after parsing the Basic Flash + *Parameter Table. + */ +static void spi_nor_init_params(struct spi_nor *nor) +{ + spi_nor_info_init_params(nor); spi_nor_manufacturer_init_params(nor); - if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && - !(info->flags & SPI_NOR_SKIP_SFDP)) { - struct spi_nor_flash_parameter sfdp_params; - - memcpy(_params, params, sizeof(sfdp_params)); - - if (spi_nor_parse_sfdp(nor, _params)) { - nor->addr_width = 0; - nor->flags &= ~SNOR_F_4B_OPCODES; - } else { - memcpy(params, _params, sizeof(*params)); - } - } - - return 0; + if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && + !(nor->info->flags & SPI_NOR_SKIP_SFDP)) + spi_nor_sfdp_init_params(nor); } static int spi_nor_select_read(struct spi_nor *nor, @@ -4670,10 +4715,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->info->flags & SPI_NOR_HAS_LOCK) nor->clear_sr_bp = spi_nor_clear_sr_bp; - /* Parse the Serial Flash Discoverable Parameters table. */ - ret = spi_nor_init_params(nor); - if (ret) - return ret; + /* Init flash parameters based on flash_info struct and SFDP */ + spi_nor_init_params(nor); if (!mtd->name) mtd->name = dev_name(dev); -- 2.9.5
[RESEND PATCH v3 12/20] mtd: spi-nor: Add spansion_post_sfdp_fixups()
From: Boris Brezillon Add a spansion_post_sfdp_fixups() function to fix the erase opcode, erase sector size and set the SNOR_F_4B_OPCODES flag. This way, all spansion related quirks are placed in the spansion_post_sfdp_fixups() function. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 37 +++-- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b8caf5171ff5..c862a59ce9df 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -591,18 +591,6 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode) static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) { - /* Do some manufacturer fixups first */ - switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_SPANSION: - /* No small sector erase for 4-byte command set */ - nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; - break; - - default: - break; - } - nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode); nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); @@ -4304,6 +4292,19 @@ static void spi_nor_info_init_params(struct spi_nor *nor) spi_nor_init_uniform_erase_map(map, erase_mask, params->size); } +static void spansion_post_sfdp_fixups(struct spi_nor *nor) +{ + struct mtd_info *mtd = >mtd; + + if (mtd->size <= SZ_16M) + return; + + nor->flags |= SNOR_F_4B_OPCODES; + /* No small sector erase for 4-byte command set */ + nor->erase_opcode = SPINOR_OP_SE; + nor->mtd.erasesize = nor->info->sector_size; +} + /** * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings * after SFDP has been parsed (is also called for SPI NORs that do not @@ -4316,6 +4317,15 @@ static void spi_nor_info_init_params(struct spi_nor *nor) */ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor) { + switch (JEDEC_MFR(nor->info)) { + case SNOR_MFR_SPANSION: + spansion_post_sfdp_fixups(nor); + break; + + default: + break; + } + if (nor->info->fixups && nor->info->fixups->post_sfdp) nor->info->fixups->post_sfdp(nor); } @@ -4862,8 +4872,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->addr_width = 3; } - if (info->flags & SPI_NOR_4B_OPCODES || - (JEDEC_MFR(info) == SNOR_MFR_SPANSION && mtd->size > SZ_16M)) + if (info->flags & SPI_NOR_4B_OPCODES) nor->flags |= SNOR_F_4B_OPCODES; if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES && -- 2.9.5
[RESEND PATCH v3 02/20] mtd: spi-nor: Use nor->params
From: Tudor Ambarus The Flash parameters and settings are now stored in 'struct spi_nor'. Use this instead of the stack allocated params. Few functions stop passing pointer to params, as they can get it from 'struct spi_nor'. spi_nor_parse_sfdp() and children will keep passing pointer to params because of the roll-back mechanism: in case the parsing of SFDP fails, the legacy flash parameter and settings will be restored. Zeroing params is no longer needed because all SPI NOR users kzalloc 'struct spi_nor'. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: collect R-b drivers/mtd/spi-nor/spi-nor.c | 46 ++- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index d35dc6a97521..e9b9cd70a999 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -2974,16 +2974,13 @@ static int spi_nor_spimem_check_pp(struct spi_nor *nor, * spi_nor_spimem_adjust_hwcaps - Find optimal Read/Write protocol *based on SPI controller capabilities * @nor:pointer to a 'struct spi_nor' - * @params: pointer to the 'struct spi_nor_flash_parameter' - * representing SPI NOR flash capabilities * @hwcaps: pointer to resulting capabilities after adjusting * according to controller and flash's capability */ static void -spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, -const struct spi_nor_flash_parameter *params, -u32 *hwcaps) +spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps) { + struct spi_nor_flash_parameter *params = >params; unsigned int cap; /* DTR modes are not supported yet, mask them all. */ @@ -4129,16 +4126,13 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } -static int spi_nor_init_params(struct spi_nor *nor, - struct spi_nor_flash_parameter *params) +static int spi_nor_init_params(struct spi_nor *nor) { + struct spi_nor_flash_parameter *params = >params; struct spi_nor_erase_map *map = >erase_map; const struct flash_info *info = nor->info; u8 i, erase_mask; - /* Set legacy flash parameters as default. */ - memset(params, 0, sizeof(*params)); - /* Set SPI NOR sizes. */ params->size = (u64)info->sector_size * info->n_sectors; params->page_size = info->page_size; @@ -4255,7 +4249,6 @@ static int spi_nor_init_params(struct spi_nor *nor, } static int spi_nor_select_read(struct spi_nor *nor, - const struct spi_nor_flash_parameter *params, u32 shared_hwcaps) { int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_READ_MASK) - 1; @@ -4268,7 +4261,7 @@ static int spi_nor_select_read(struct spi_nor *nor, if (cmd < 0) return -EINVAL; - read = >reads[cmd]; + read = >params.reads[cmd]; nor->read_opcode = read->opcode; nor->read_proto = read->proto; @@ -4287,7 +4280,6 @@ static int spi_nor_select_read(struct spi_nor *nor, } static int spi_nor_select_pp(struct spi_nor *nor, -const struct spi_nor_flash_parameter *params, u32 shared_hwcaps) { int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_PP_MASK) - 1; @@ -4300,7 +4292,7 @@ static int spi_nor_select_pp(struct spi_nor *nor, if (cmd < 0) return -EINVAL; - pp = >page_programs[cmd]; + pp = >params.page_programs[cmd]; nor->program_opcode = pp->opcode; nor->write_proto = pp->proto; return 0; @@ -4407,9 +4399,9 @@ static int spi_nor_select_erase(struct spi_nor *nor, u32 wanted_size) } static int spi_nor_setup(struct spi_nor *nor, -const struct spi_nor_flash_parameter *params, const struct spi_nor_hwcaps *hwcaps) { + struct spi_nor_flash_parameter *params = >params; u32 ignored_mask, shared_mask; bool enable_quad_io; int err; @@ -4426,7 +4418,7 @@ static int spi_nor_setup(struct spi_nor *nor, * need to discard some of them based on what the SPI * controller actually supports (using spi_mem_supports_op()). */ - spi_nor_spimem_adjust_hwcaps(nor, params, _mask); + spi_nor_spimem_adjust_hwcaps(nor, _mask); } else { /* * SPI n-n-n protocols are not supported when the SPI @@ -4442,7 +4434,7 @@ static int spi_nor_setup(struct spi_nor *nor, } /* Select the (Fast) Read command. */ - err = spi_nor_select_read(nor, params, shared_mask); + err = spi_nor_select_read(nor, shared_mask); if (err) { dev_err(nor->dev,
[RESEND PATCH v3 04/20] mtd: spi-nor: Move erase_map to 'struct spi_nor_flash_parameter'
From: Tudor Ambarus All flash parameters and settings should reside inside 'struct spi_nor_flash_parameter'. Move the SMPT parsed erase map from 'struct spi_nor' to 'struct spi_nor_flash_parameter'. Please note that there is a roll-back mechanism for the flash parameter and settings, for cases when SFDP parser fails. The SFDP parser receives a Stack allocated copy of nor->params, called sfdp_params, and uses it to retrieve the serial flash discoverable parameters. JESD216 SFDP is a standard and has a higher priority than the default initialized flash parameters, so will overwrite the sfdp_params data when needed. All SFDP code uses the local copy of nor->params, that will overwrite it in the end, if the parser succeds. Saving and restoring the nor->params.erase_map is no longer needed, since the SFDP code does not touch it. Signed-off-by: Tudor Ambarus --- v3: Collect R-b drivers/mtd/spi-nor/spi-nor.c | 40 +--- include/linux/mtd/spi-nor.h | 8 +--- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index effda372cb33..9dd6cd8cd13c 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -600,7 +600,7 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); if (!spi_nor_has_uniform_erase(nor)) { - struct spi_nor_erase_map *map = >erase_map; + struct spi_nor_erase_map *map = >params.erase_map; struct spi_nor_erase_type *erase; int i; @@ -1133,7 +1133,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor, struct list_head *erase_list, u64 addr, u32 len) { - const struct spi_nor_erase_map *map = >erase_map; + const struct spi_nor_erase_map *map = >params.erase_map; const struct spi_nor_erase_type *erase, *prev_erase = NULL; struct spi_nor_erase_region *region; struct spi_nor_erase_command *cmd = NULL; @@ -3328,7 +3328,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, struct spi_nor_flash_parameter *params) { - struct spi_nor_erase_map *map = >erase_map; + struct spi_nor_erase_map *map = >erase_map; struct spi_nor_erase_type *erase_type = map->erase_type; struct sfdp_bfpt bfpt; size_t len; @@ -3409,7 +3409,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, * Erase Types defined in the bfpt table. */ erase_mask = 0; - memset(>erase_map, 0, sizeof(nor->erase_map)); + memset(>erase_map, 0, sizeof(params->erase_map)); for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) { const struct sfdp_bfpt_erase *er = _bfpt_erases[i]; u32 erasesize; @@ -3684,14 +3684,18 @@ spi_nor_region_check_overlay(struct spi_nor_erase_region *region, /** * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map * @nor: pointer to a 'struct spi_nor' + * @params: pointer to a duplicate 'struct spi_nor_flash_parameter' that is + * used for storing SFDP parsed data * @smpt: pointer to the sector map parameter table * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, - const u32 *smpt) +static int +spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, + struct spi_nor_flash_parameter *params, + const u32 *smpt) { - struct spi_nor_erase_map *map = >erase_map; + struct spi_nor_erase_map *map = >erase_map; struct spi_nor_erase_type *erase = map->erase_type; struct spi_nor_erase_region *region; u64 offset; @@ -3770,6 +3774,8 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, * spi_nor_parse_smpt() - parse Sector Map Parameter Table * @nor: pointer to a 'struct spi_nor' * @smpt_header: sector map parameter table header + * @params:pointer to a duplicate 'struct spi_nor_flash_parameter' + * that is used for storing SFDP parsed data * * This table is optional, but when available, we parse it to identify the * location and size of sectors within the main data array of the flash memory @@ -3778,7 +3784,8 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, * Return: 0 on success, -errno otherwise. */ static int spi_nor_parse_smpt(struct spi_nor *nor, - const struct sfdp_parameter_header *smpt_header) + const struct sfdp_parameter_header *smpt_header, +
[RESEND PATCH v3 03/20] mtd: spi-nor: Drop quad_enable() from 'struct spi-nor'
From: Tudor Ambarus All flash parameters and settings should reside inside 'struct spi_nor_flash_parameter'. Drop the local copy of quad_enable() and use the one from 'struct spi_nor_flash_parameter'. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: Collect R-b drivers/mtd/spi-nor/spi-nor.c | 40 +++- include/linux/mtd/spi-nor.h | 2 -- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index e9b9cd70a999..effda372cb33 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4403,7 +4403,6 @@ static int spi_nor_setup(struct spi_nor *nor, { struct spi_nor_flash_parameter *params = >params; u32 ignored_mask, shared_mask; - bool enable_quad_io; int err; /* @@ -4457,23 +4456,33 @@ static int spi_nor_setup(struct spi_nor *nor, return err; } - /* Enable Quad I/O if needed. */ - enable_quad_io = (spi_nor_get_protocol_width(nor->read_proto) == 4 || - spi_nor_get_protocol_width(nor->write_proto) == 4); - if (enable_quad_io && params->quad_enable) - nor->quad_enable = params->quad_enable; - else - nor->quad_enable = NULL; - return 0; } +/** + * spi_nor_quad_enable() - enable Quad I/O if needed. + * @nor:pointer to a 'struct spi_nor' + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_quad_enable(struct spi_nor *nor) +{ + if (!nor->params.quad_enable) + return 0; + + if (!(spi_nor_get_protocol_width(nor->read_proto) == 4 || + spi_nor_get_protocol_width(nor->write_proto) == 4)) + return 0; + + return nor->params.quad_enable(nor); +} + static int spi_nor_init(struct spi_nor *nor) { int err; if (nor->clear_sr_bp) { - if (nor->quad_enable == spansion_quad_enable) + if (nor->params.quad_enable == spansion_quad_enable) nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp; err = nor->clear_sr_bp(nor); @@ -4484,12 +4493,10 @@ static int spi_nor_init(struct spi_nor *nor) } } - if (nor->quad_enable) { - err = nor->quad_enable(nor); - if (err) { - dev_err(nor->dev, "quad mode not supported\n"); - return err; - } + err = spi_nor_quad_enable(nor); + if (err) { + dev_err(nor->dev, "quad mode not supported\n"); + return err; } if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) { @@ -4706,7 +4713,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, * - select op codes for (Fast) Read, Page Program and Sector Erase. * - set the number of dummy cycles (mode cycles + wait states). * - set the SPI protocols for register and memory accesses. -* - set the Quad Enable bit if needed (required by SPI x-y-4 protos). */ ret = spi_nor_setup(nor, hwcaps); if (ret) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 77ba692d9348..17787238f0e9 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -535,7 +535,6 @@ struct flash_info; * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is * completely locked - * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @clear_sr_bp: [FLASH-SPECIFIC] clears the Block Protection Bits from * the SPI NOR Status Register. * @params:[FLASH-SPECIFIC] SPI-NOR flash parameters and settings. @@ -579,7 +578,6 @@ struct spi_nor { int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*quad_enable)(struct spi_nor *nor); int (*clear_sr_bp)(struct spi_nor *nor); struct spi_nor_flash_parameter params; -- 2.9.5
[RESEND PATCH v3 06/20] mtd: spi-nor: Add a default_init() fixup hook for gd25q256
From: Boris Brezillon gd25q256 needs to tweak the ->quad_enable() implementation and the ->default_init() fixup hook is the perfect place to do that. This way, if we ever need to tweak more things for this flash, we won't have to add new fields in flash_info. We can get rid of the flash_info->quad_enable field as gd25q256 was the only user. Signed-off-by: Boris Brezillon [tudor.amba...@microchip.com: use ->default_init() hook instead of ->post_sfdp()] Signed-off-by: Tudor Ambarus --- v3: no changes drivers/mtd/spi-nor/spi-nor.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 8fd60e1eebd2..3dbbfe34d1d2 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -222,8 +222,6 @@ struct flash_info { /* Part specific fixup hooks. */ const struct spi_nor_fixups *fixups; - - int (*quad_enable)(struct spi_nor *nor); }; #define JEDEC_MFR(info)((info)->id[0]) @@ -2126,6 +2124,21 @@ static struct spi_nor_fixups mx25l25635_fixups = { .post_bfpt = mx25l25635_post_bfpt_fixups, }; +static void gd25q256_default_init(struct spi_nor *nor) +{ + /* +* Some manufacturer like GigaDevice may use different +* bit to set QE on different memories, so the MFR can't +* indicate the quad_enable method for this case, we need +* to set it in the default_init fixup hook. +*/ + nor->params.quad_enable = macronix_quad_enable; +} + +static struct spi_nor_fixups gd25q256_fixups = { + .default_init = gd25q256_default_init, +}; + /* NOTE: double check command sets and memory organization when you add * more nor chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. @@ -2218,7 +2231,7 @@ static const struct flash_info spi_nor_ids[] = { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - .quad_enable = macronix_quad_enable, + .fixups = _fixups, }, /* Intel/Numonyx -- xxxs33b */ @@ -4237,15 +4250,6 @@ static int spi_nor_init_params(struct spi_nor *nor) params->quad_enable = spansion_quad_enable; break; } - - /* -* Some manufacturer like GigaDevice may use different -* bit to set QE on different memories, so the MFR can't -* indicate the quad_enable method for this case, we need -* set it in flash info list. -*/ - if (info->quad_enable) - params->quad_enable = info->quad_enable; } spi_nor_manufacturer_init_params(nor); -- 2.9.5
[RESEND PATCH v3 00/20] mtd: spi-nor: move manuf out of the core
From: Tudor Ambarus v3: - Drop patches: "mtd: spi-nor: Move clear_sr_bp() to 'struct spi_nor_flash_parameter'" "mtd: spi-nor: Rework the disabling of block write protection" and replace them with the RFC patch: "mtd: spi-nor: Rework the disabling of block write protection" - rename spi_nor_legacy_init_params() to spi_nor_info_init_params() - rebase patches and send them all in a single patch set. v2: - addressed all the comments - all flash parameters and settings are now set in 'struct spi_nor_flash_parameter', for a clearer separation between the SPI NOR layer and the flash params. In order to test this, you'll have to merge v5.3-rc5 in spi-nor/next. This patch set depends on 'commit 834de5c1aa76 ("mtd: spi-nor: Fix the disabling of write protection at init") The scope of the "mtd: spi-nor: move manuf out of the core" batches, is to move all manufacturer specific code out of the spi-nor core. In the quest of removing the manufacturer specific code from the spi-nor core, we want to impose a timeline/priority on how the flash parameters are updated. As of now. the flash parameters initialization logic is as following: a/ default flash parameters init in spi_nor_init_params() b/ manufacturer specific flash parameters updates, split across entire spi-nor core code c/ flash parameters updates based on SFDP tables d/ post BFPT flash parameter updates With the "mtd: spi-nor: move manuf out of the core" batches, we want to impose the following sequence of calls: 1/ spi-nor core legacy flash parameters init: spi_nor_default_init_params() 2/ MFR-based manufacturer flash parameters init: nor->manufacturer->fixups->default_init() 3/ specific flash_info tweeks done when decisions can not be done just on MFR: nor->info->fixups->default_init() 4/ SFDP tables flash parameters init - SFDP knows better: spi_nor_sfdp_init_params() 5/ post SFDP tables flash parameters updates - in case manufacturers get the serial flash tables wrong or incomplete. nor->info->fixups->post_sfdp() The later can be extended to nor->manufacturer->fixups->post_sfdp() if needed. Setting of flash parameters will no longer be spread interleaved across the spi-nor core, there will be a clear separation on who and when will update the flash parameters. Tested on sst26vf064b with atmel-quadspi SPIMEM driver. Boris Brezillon (7): mtd: spi-nor: Add a default_init() fixup hook for gd25q256 mtd: spi-nor: Create a ->set_4byte() method mtd: spi-nor: Rework the SPI NOR lock/unlock logic mtd: spi-nor: Add post_sfdp() hook to tweak flash config mtd: spi-nor: Add spansion_post_sfdp_fixups() mtd: spi-nor: Add a ->convert_addr() method mtd: spi-nor: Add the SPI_NOR_XSR_RDY flag Tudor Ambarus (13): mtd: spi-nor: Regroup flash parameter and settings mtd: spi-nor: Use nor->params mtd: spi-nor: Drop quad_enable() from 'struct spi-nor' mtd: spi-nor: Move erase_map to 'struct spi_nor_flash_parameter' mtd: spi-nor: Add default_init() hook to tweak flash parameters mtd: spi_nor: Move manufacturer quad_enable() in ->default_init() mtd: spi-nor: Split spi_nor_init_params() mtd: spi_nor: Add a ->setup() method mtd: spi-nor: Add s3an_post_sfdp_fixups() mtd: spi-nor: Bring flash params init together mtd: spi_nor: Introduce spi_nor_set_addr_width() mtd: spi-nor: Introduce spi_nor_get_flash_info() mtd: spi-nor: Rework the disabling of block write protection drivers/mtd/spi-nor/spi-nor.c | 1304 +++-- include/linux/mtd/spi-nor.h | 298 +++--- 2 files changed, 927 insertions(+), 675 deletions(-) -- 2.9.5
[RESEND PATCH v3 01/20] mtd: spi-nor: Regroup flash parameter and settings
From: Tudor Ambarus The scope is to move all [FLASH-SPECIFIC] parameters and settings from 'struct spi_nor' to 'struct spi_nor_flash_parameter'. 'struct spi_nor_flash_parameter' describes the hardware capabilities and associated settings of the SPI NOR flash memory. It includes legacy flash parameters and settings that can be overwritten by the spi_nor_fixups hooks, or dynamically when parsing the JESD216 Serial Flash Discoverable Parameters (SFDP) tables. All SFDP params and settings will fit inside 'struct spi_nor_flash_parameter'. Move spi_nor_hwcaps related code to avoid forward declarations. Add a forward declaration that we can't avoid: 'struct spi_nor' will be used in 'struct spi_nor_flash_parameter'. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: collect R-b drivers/mtd/spi-nor/spi-nor.c | 65 include/linux/mtd/spi-nor.h | 239 +- 2 files changed, 164 insertions(+), 140 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 0597cb8257b0..d35dc6a97521 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -40,71 +40,6 @@ #define SPI_NOR_MAX_ID_LEN 6 #define SPI_NOR_MAX_ADDR_WIDTH 4 -struct spi_nor_read_command { - u8 num_mode_clocks; - u8 num_wait_states; - u8 opcode; - enum spi_nor_protocol proto; -}; - -struct spi_nor_pp_command { - u8 opcode; - enum spi_nor_protocol proto; -}; - -enum spi_nor_read_command_index { - SNOR_CMD_READ, - SNOR_CMD_READ_FAST, - SNOR_CMD_READ_1_1_1_DTR, - - /* Dual SPI */ - SNOR_CMD_READ_1_1_2, - SNOR_CMD_READ_1_2_2, - SNOR_CMD_READ_2_2_2, - SNOR_CMD_READ_1_2_2_DTR, - - /* Quad SPI */ - SNOR_CMD_READ_1_1_4, - SNOR_CMD_READ_1_4_4, - SNOR_CMD_READ_4_4_4, - SNOR_CMD_READ_1_4_4_DTR, - - /* Octal SPI */ - SNOR_CMD_READ_1_1_8, - SNOR_CMD_READ_1_8_8, - SNOR_CMD_READ_8_8_8, - SNOR_CMD_READ_1_8_8_DTR, - - SNOR_CMD_READ_MAX -}; - -enum spi_nor_pp_command_index { - SNOR_CMD_PP, - - /* Quad SPI */ - SNOR_CMD_PP_1_1_4, - SNOR_CMD_PP_1_4_4, - SNOR_CMD_PP_4_4_4, - - /* Octal SPI */ - SNOR_CMD_PP_1_1_8, - SNOR_CMD_PP_1_8_8, - SNOR_CMD_PP_8_8_8, - - SNOR_CMD_PP_MAX -}; - -struct spi_nor_flash_parameter { - u64 size; - u32 page_size; - - struct spi_nor_hwcaps hwcaps; - struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; - struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; - - int (*quad_enable)(struct spi_nor *nor); -}; - struct sfdp_parameter_header { u8 id_lsb; u8 minor; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 3075ac73b171..77ba692d9348 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -334,6 +334,165 @@ struct spi_nor_erase_map { }; /** + * struct spi_nor_hwcaps - Structure for describing the hardware capabilies + * supported by the SPI controller (bus master). + * @mask: the bitmask listing all the supported hw capabilies + */ +struct spi_nor_hwcaps { + u32 mask; +}; + +/* + *(Fast) Read capabilities. + * MUST be ordered by priority: the higher bit position, the higher priority. + * As a matter of performances, it is relevant to use Octal SPI protocols first, + * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly + * (Slow) Read. + */ +#define SNOR_HWCAPS_READ_MASK GENMASK(14, 0) +#define SNOR_HWCAPS_READ BIT(0) +#define SNOR_HWCAPS_READ_FAST BIT(1) +#define SNOR_HWCAPS_READ_1_1_1_DTR BIT(2) + +#define SNOR_HWCAPS_READ_DUAL GENMASK(6, 3) +#define SNOR_HWCAPS_READ_1_1_2 BIT(3) +#define SNOR_HWCAPS_READ_1_2_2 BIT(4) +#define SNOR_HWCAPS_READ_2_2_2 BIT(5) +#define SNOR_HWCAPS_READ_1_2_2_DTR BIT(6) + +#define SNOR_HWCAPS_READ_QUAD GENMASK(10, 7) +#define SNOR_HWCAPS_READ_1_1_4 BIT(7) +#define SNOR_HWCAPS_READ_1_4_4 BIT(8) +#define SNOR_HWCAPS_READ_4_4_4 BIT(9) +#define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) + +#define SNOR_HWCAPS_READ_OCTAL GENMASK(14, 11) +#define SNOR_HWCAPS_READ_1_1_8 BIT(11) +#define SNOR_HWCAPS_READ_1_8_8 BIT(12) +#define SNOR_HWCAPS_READ_8_8_8 BIT(13) +#define SNOR_HWCAPS_READ_1_8_8_DTR BIT(14) + +/* + * Page Program capabilities. + * MUST be ordered by priority: the higher bit position, the higher priority. + * Like (Fast) Read capabilities, Octal/Quad SPI protocols are preferred to the + * legacy SPI 1-1-1 protocol. + * Note that Dual Page Programs are not supported because there is no existing + *
[RESEND PATCH v3 05/20] mtd: spi-nor: Add default_init() hook to tweak flash parameters
From: Tudor Ambarus As of now, the flash parameters initialization logic is as following: a/ default flash parameters init in spi_nor_init_params() b/ manufacturer specific flash parameters updates, split across entire spi-nor core code c/ flash parameters updates based on SFDP tables d/ post BFPT flash parameter updates In the quest of removing the manufacturer specific code from the spi-nor core, we want to impose a timeline/priority on how the flash parameters are updated. The following sequence of calls is pursued: 1/ spi-nor core parameters init based on 'flash_info' struct: spi_nor_info_init_params() which can be overwritten by: 2/ MFR-based manufacturer flash parameters init: nor->manufacturer->fixups->default_init() which can be overwritten by: 3/ specific flash_info tweeks done when decisions can not be done just on MFR: nor->info->fixups->default_init() which can be overwritten by: 4/ SFDP tables flash parameters init - SFDP knows better: spi_nor_sfdp_init_params() which can be overwritten by: 5/ post SFDP tables flash parameters updates - in case manufacturers get the serial flash tables wrong or incomplete. nor->info->fixups->post_sfdp() The later can be extended to nor->manufacturer->fixups->post_sfdp() if needed. This patch opens doors for steps 2/ and 3/. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: reword description drivers/mtd/spi-nor/spi-nor.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 9dd6cd8cd13c..8fd60e1eebd2 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -154,12 +154,16 @@ struct sfdp_bfpt { /** * struct spi_nor_fixups - SPI NOR fixup hooks + * @default_init: called after default flash parameters init. Used to tweak + *flash parameters when information provided by the flash_info + *table is incomplete or wrong. * @post_bfpt: called after the BFPT table has been parsed * * Those hooks can be used to tweak the SPI NOR configuration when the SFDP * table is broken or not available. */ struct spi_nor_fixups { + void (*default_init)(struct spi_nor *nor); int (*post_bfpt)(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt, @@ -4133,6 +4137,17 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } +/** + * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and + * settings based on ->default_init() hook. + * @nor: pointer to a 'struct spi-nor'. + */ +static void spi_nor_manufacturer_init_params(struct spi_nor *nor) +{ + if (nor->info->fixups && nor->info->fixups->default_init) + nor->info->fixups->default_init(nor); +} + static int spi_nor_init_params(struct spi_nor *nor) { struct spi_nor_flash_parameter *params = >params; @@ -4233,6 +4248,8 @@ static int spi_nor_init_params(struct spi_nor *nor) params->quad_enable = info->quad_enable; } + spi_nor_manufacturer_init_params(nor); + if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && !(info->flags & SPI_NOR_SKIP_SFDP)) { struct spi_nor_flash_parameter sfdp_params; -- 2.9.5
Re: [PATCH] [media] pvrusb2: qctrl.flag will be uninitlaized if cx2341x_ctrl_query() returns error code
On 8/21/19 11:09 PM, Yizhuo wrote: > Inside function ctrl_cx2341x_getv4lflags(), qctrl.flag > will be uninitlaized if cx2341x_ctrl_query() returns -EINVAL. > However, it will be used in the later if statement, which is > potentially unsafe. > > Signed-off-by: Yizhuo > --- > drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c > b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c > index ad5b25b89699..1fa05971316a 100644 > --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c > +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c > @@ -793,6 +793,7 @@ static unsigned int ctrl_cx2341x_getv4lflags(struct > pvr2_ctrl *cptr) > struct v4l2_queryctrl qctrl; > struct pvr2_ctl_info *info; > qctrl.id = cptr->info->v4l_id; > + memset(, 0, sizeof(qctrl)) Please compile test your patches! This doesn't compile due to a typo (qctr -> qctrl). Also, this would overwrite qctrl.id with 0, not what you want. Instead, just do: struct v4l2_queryctrl qctrl = {}; to initialize the struct with all 0. Regards, Hans > cx2341x_ctrl_query(>hdw->enc_ctl_state,); > /* Strip out the const so we can adjust a function pointer. It's > OK to do this here because we know this is a dynamically created >
Re: [PATCH] powerpc/time: use feature fixup in __USE_RTC() instead of cpu feature.
On Mon, Aug 26, 2019 at 09:41:39PM +1000, Michael Ellerman wrote: > Given how many 601 users there are, maybe 1?, I think that would be a > simpler option and avoids complicating the code / binary for everyone > else. Or you could remove 601 support altogether? Segher
Re: [PATCH v1] scsi: ufs: Disable local LCC in .link_startup_notify() in Cadence UFS
Hi, On 13/08/19 1:12 PM, Anil Varughese wrote: > Some UFS devices have issues if LCC is enabled. So we > are setting PA_LOCAL_TX_LCC_Enable to 0 before link > startup which will make sure that both host and device > TX LCC are disabled once link startup is completed. > > Signed-off-by: Anil Varughese > --- Reviewed-by: Vignesh Raghavendra Regards Vignesh > drivers/scsi/ufs/cdns-pltfrm.c | 27 +++ > 1 file changed, 27 insertions(+) > > diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c > index 993519080..b2af04c57 100644 > --- a/drivers/scsi/ufs/cdns-pltfrm.c > +++ b/drivers/scsi/ufs/cdns-pltfrm.c > @@ -77,6 +77,31 @@ static int cdns_ufs_hce_enable_notify(struct ufs_hba *hba, > return cdns_ufs_set_hclkdiv(hba); > } > > +/** > + * Called before and after Link startup is carried out. > + * @hba: host controller instance > + * @status: notify stage (pre, post change) > + * > + * Return zero for success and non-zero for failure > + */ > +static int cdns_ufs_link_startup_notify(struct ufs_hba *hba, > + enum ufs_notify_change_status status) > +{ > + if (status != PRE_CHANGE) > + return 0; > + > + /* > + * Some UFS devices have issues if LCC is enabled. > + * So we are setting PA_Local_TX_LCC_Enable to 0 > + * before link startup which will make sure that both host > + * and device TX LCC are disabled once link startup is > + * completed. > + */ > + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); > + > + return 0; > +} > + > /** > * cdns_ufs_init - performs additional ufs initialization > * @hba: host controller instance > @@ -114,12 +139,14 @@ static int cdns_ufs_m31_16nm_phy_initialization(struct > ufs_hba *hba) > static const struct ufs_hba_variant_ops cdns_ufs_pltfm_hba_vops = { > .name = "cdns-ufs-pltfm", > .hce_enable_notify = cdns_ufs_hce_enable_notify, > + .link_startup_notify = cdns_ufs_link_startup_notify, > }; > > static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = { > .name = "cdns-ufs-pltfm", > .init = cdns_ufs_init, > .hce_enable_notify = cdns_ufs_hce_enable_notify, > + .link_startup_notify = cdns_ufs_link_startup_notify, > .phy_initialization = cdns_ufs_m31_16nm_phy_initialization, > }; > > -- Regards Vignesh
Re: [RFC PATCH] mm: drop mark_page_access from the unmap path
On Tue 13-08-19 12:51:43, Michal Hocko wrote: > On Mon 12-08-19 11:07:25, Johannes Weiner wrote: > > On Mon, Aug 12, 2019 at 10:09:47AM +0200, Michal Hocko wrote: [...] > > > > Maybe the refaults will be fine - but latency expectations around > > > > mapped page cache certainly are a lot higher than unmapped cache. > > > > > > > > So I'm a bit reluctant about this patch. If Minchan can be happy with > > > > the lock batching, I'd prefer that. > > > > > > Yes, it seems that the regular lock drop helps in Minchan's case > > > but this is a kind of change that might have other subtle side effects. > > > E.g. will-it-scale has noticed a regression [1], likely because the > > > critical section is shorter and the overal throughput of the operation > > > decreases. Now, the w-i-s is an artificial benchmark so I wouldn't lose > > > much sleep over it normally but we have already seen real regressions > > > when the locking pattern has changed in the past so I would by a bit > > > cautious. > > > > I'm much more concerned about fundamentally changing the aging policy > > of mapped page cache then about the lock breaking scheme. With locking > > we worry about CPU effects; with aging we worry about additional IO. > > But the later is observable and debuggable little bit easier IMHO. > People are quite used to watch for major faults from my experience > as that is an easy metric to compare. > > > > As I've said, this RFC is mostly to open a discussion. I would really > > > like to weigh the overhead of mark_page_accessed and potential scenario > > > when refaults would be visible in practice. I can imagine that a short > > > lived statically linked applications have higher chance of being the > > > only user unlike libraries which are often being mapped via several > > > ptes. But the main problem to evaluate this is that there are many other > > > external factors to trigger the worst case. > > > > We can discuss the pros and cons, but ultimately we simply need to > > test it against real workloads to see if changing the promotion rules > > regresses the amount of paging we do in practice. > > Agreed. Do you see other option than to try it out and revert if we see > regressions? We would get a workload description which would be helpful > for future regression testing when touching this area. We can start > slower and keep it in linux-next for a release cycle to catch any > fallouts early. > > Thoughts? ping... -- Michal Hocko SUSE Labs
Re: [RFC 7/9] dt-bindings: rtc: s3c: Convert S3C/Exynos RTC bindings to json-schema
On Fri, Aug 23, 2019 at 9:54 AM Krzysztof Kozlowski wrote: > > Convert Samsung S3C/Exynos Real Time Clock bindings to DT schema format > using json-schema. > > Signed-off-by: Krzysztof Kozlowski > --- > .../devicetree/bindings/rtc/s3c-rtc.txt | 31 -- > .../devicetree/bindings/rtc/s3c-rtc.yaml | 95 +++ > 2 files changed, 95 insertions(+), 31 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/rtc/s3c-rtc.txt > create mode 100644 Documentation/devicetree/bindings/rtc/s3c-rtc.yaml > diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml > b/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml > new file mode 100644 > index ..44b021812a83 > --- /dev/null > +++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml > @@ -0,0 +1,95 @@ > +# SPDX-License-Identifier: GPL-2.0 > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/rtc/s3c-rtc.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Samsung S3C, S5P and Exynos Real Time Clock controller > + > +maintainers: > + - Krzysztof Kozlowski > + > +# Select also deprecated compatibles (for finding deprecate usage) > +select: > + properties: > +compatible: > + items: > +- enum: > +- samsung,s3c2410-rtc > +- samsung,s3c2416-rtc > +- samsung,s3c2443-rtc > +- samsung,s3c6410-rtc > +# Deprecated, use samsung,s3c6410-rtc > +- samsung,exynos3250-rtc We've come up with a better way of doing this that doesn't need a custom 'select'. Add a 'oneOf' to compatible and add another entry: - const: samsung,exynos3250-rtc deprecated: true It's not implemented yet in the tool, but we'll keep the compatible for 'select' and otherwise drop schema marked deprecated. > + required: > +- compatible > + > +properties: > + compatible: > +items: > + - enum: You can drop 'items' when there's only 1 entry. > + - samsung,s3c2410-rtc > + - samsung,s3c2416-rtc > + - samsung,s3c2443-rtc > + - samsung,s3c6410-rtc > + reg: > +maxItems: 1 > + > + clocks: > +description: > + Must contain a list of phandle and clock specifier for the rtc > + clock and in the case of a s3c6410 compatible controller, also > + a source clock. > +minItems: 1 > +maxItems: 2 > + > + clock-names: > +description: > + Must contain "rtc" and for a s3c6410 compatible controller, > + a "rtc_src" sorted in the same order as the clocks property. > +oneOf: > + - items: > + - const: rtc > + - items: > + # TODO: This can be in any order matching clocks, how to express > it? It shouldn't be in any order. Fix the dts files. > + - const: rtc > + - const: rtc_src You should drop all this and add an else clause below. > + > + interrupts: > +description: > + Two interrupt numbers to the cpu should be specified. First > + interrupt number is the rtc alarm interrupt and second interrupt number > + is the rtc tick interrupt. The number of cells representing a interrupt > + depends on the parent interrupt controller. > +minItems: 2 > +maxItems: 2 > + > +allOf: > + - if: > + properties: > +compatible: > + contains: > +enum: > + - samsung,s3c6410-rtc > + - samsung,exynos3250-rtc > + > +then: > + properties: > +clocks: > + minItems: 2 > + maxItems: 2 > +clock-names: > + items: > + - const: rtc > + - const: rtc_src Should be indented 2 more spaces. > + > +examples: > + - | > +rtc@1007 { > + compatible = "samsung,s3c6410-rtc"; > + reg = <0x1007 0x100>; > + interrupts = <0 44 4>, <0 45 4>; > + clocks = < 0>, // CLK_RTC > + <_osc 0>; // S2MPS11_CLK_AP > + clock-names = "rtc", "rtc_src"; > +}; > -- > 2.17.1 >
Re: [PATCH] watchdog: imx2_wdt: fix min() calculation in imx2_wdt_set_timeout
On 12/08/2019 15.28, Guenter Roeck wrote: > On 8/12/19 6:13 AM, Rasmus Villemoes wrote: >> Converting from ms to s requires dividing by 1000, not multiplying. So >> this is currently taking the smaller of new_timeout and 1.28e8, >> i.e. effectively new_timeout. >> >> The driver knows what it set max_hw_heartbeat_ms to, so use that >> value instead of doing a division at run-time. >> >> FWIW, this can easily be tested by booting into a busybox shell and >> doing "watchdog -t 5 -T 130 /dev/watchdog" - without this patch, the >> watchdog fires after 130&127 == 2 seconds. >> >> Fixes: b07e228eee69 "watchdog: imx2_wdt: Fix set_timeout for big >> timeout values" >> Cc: sta...@vger.kernel.org # 5.2 plus anything the above got >> backported to >> Signed-off-by: Rasmus Villemoes > > Reviewed-by: Guenter Roeck I'm not seeing this in v5.3-rc6, did it get picked up? Rasmus
[PATCH v3 12/20] mtd: spi-nor: Add spansion_post_sfdp_fixups()
From: Boris Brezillon Add a spansion_post_sfdp_fixups() function to fix the erase opcode, erase sector size and set the SNOR_F_4B_OPCODES flag. This way, all spansion related quirks are placed in the spansion_post_sfdp_fixups() function. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 37 +++-- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b8caf5171ff5..c862a59ce9df 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -591,18 +591,6 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode) static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) { - /* Do some manufacturer fixups first */ - switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_SPANSION: - /* No small sector erase for 4-byte command set */ - nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; - break; - - default: - break; - } - nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode); nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); @@ -4304,6 +4292,19 @@ static void spi_nor_info_init_params(struct spi_nor *nor) spi_nor_init_uniform_erase_map(map, erase_mask, params->size); } +static void spansion_post_sfdp_fixups(struct spi_nor *nor) +{ + struct mtd_info *mtd = >mtd; + + if (mtd->size <= SZ_16M) + return; + + nor->flags |= SNOR_F_4B_OPCODES; + /* No small sector erase for 4-byte command set */ + nor->erase_opcode = SPINOR_OP_SE; + nor->mtd.erasesize = nor->info->sector_size; +} + /** * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings * after SFDP has been parsed (is also called for SPI NORs that do not @@ -4316,6 +4317,15 @@ static void spi_nor_info_init_params(struct spi_nor *nor) */ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor) { + switch (JEDEC_MFR(nor->info)) { + case SNOR_MFR_SPANSION: + spansion_post_sfdp_fixups(nor); + break; + + default: + break; + } + if (nor->info->fixups && nor->info->fixups->post_sfdp) nor->info->fixups->post_sfdp(nor); } @@ -4862,8 +4872,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->addr_width = 3; } - if (info->flags & SPI_NOR_4B_OPCODES || - (JEDEC_MFR(info) == SNOR_MFR_SPANSION && mtd->size > SZ_16M)) + if (info->flags & SPI_NOR_4B_OPCODES) nor->flags |= SNOR_F_4B_OPCODES; if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES && -- 2.9.5
[PATCH v3 11/20] mtd: spi-nor: Add post_sfdp() hook to tweak flash config
From: Boris Brezillon SFDP tables are sometimes wrong and we need a way to override the config chosen by the SFDP parsing logic without discarding all of it. Add a new hook called after the SFDP parsing has taken place to deal with such problems. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 33 - 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 3f997797fa9d..b8caf5171ff5 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -158,6 +158,11 @@ struct sfdp_bfpt { *flash parameters when information provided by the flash_info *table is incomplete or wrong. * @post_bfpt: called after the BFPT table has been parsed + * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs + * that do not support RDSFDP). Typically used to tweak various + * parameters that could not be extracted by other means (i.e. + * when information provided by the SFDP/flash_info tables are + * incomplete or wrong). * * Those hooks can be used to tweak the SPI NOR configuration when the SFDP * table is broken or not available. @@ -168,6 +173,7 @@ struct spi_nor_fixups { const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt, struct spi_nor_flash_parameter *params); + void (*post_sfdp)(struct spi_nor *nor); }; struct flash_info { @@ -4299,6 +4305,22 @@ static void spi_nor_info_init_params(struct spi_nor *nor) } /** + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings + * after SFDP has been parsed (is also called for SPI NORs that do not + * support RDSFDP). + * @nor: pointer to a 'struct spi_nor' + * + * Typically used to tweak various parameters that could not be extracted by + * other means (i.e. when information provided by the SFDP/flash_info tables + * are incomplete or wrong). + */ +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor) +{ + if (nor->info->fixups && nor->info->fixups->post_sfdp) + nor->info->fixups->post_sfdp(nor); +} + +/** * spi_nor_late_init_params() - Late initialization of default flash parameters. * @nor: pointer to a 'struct spi_nor' * @@ -4341,7 +4363,14 @@ static void spi_nor_late_init_params(struct spi_nor *nor) *flash parameters and settings imediately after parsing the Basic Flash *Parameter Table. * - * 4/ Late default flash parameters initialization, used when the + * which can be overwritten by: + * 4/ Post SFDP flash parameters initialization. Used to tweak various + *parameters that could not be extracted by other means (i.e. when + *information provided by the SFDP/flash_info tables are incomplete or + *wrong). + * spi_nor_post_sfdp_fixups() + * + * 5/ Late default flash parameters initialization, used when the * ->default_init() hook or the SFDP parser do not set specific params. * spi_nor_late_init_params() */ @@ -4355,6 +4384,8 @@ static void spi_nor_init_params(struct spi_nor *nor) !(nor->info->flags & SPI_NOR_SKIP_SFDP)) spi_nor_sfdp_init_params(nor); + spi_nor_post_sfdp_fixups(nor); + spi_nor_late_init_params(nor); } -- 2.9.5
[PATCH v3 13/20] mtd: spi-nor: Add a ->convert_addr() method
From: Boris Brezillon In order to separate manufacturer quirks from the core we need to get rid of all the manufacturer specific flags, like the SNOR_F_S3AN_ADDR_DEFAULT one. This can easily be replaced by a ->convert_addr() hook, which when implemented will provide the core with an easy way to convert an absolute address into something the flash understands. Right now the only user are the S3AN chips, but other manufacturers can implement it if needed. Signed-off-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: no changes, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 24 ++-- include/linux/mtd/spi-nor.h | 17 ++--- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index c862a59ce9df..b96a7066a36c 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -899,10 +899,9 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) * Addr can safely be unsigned int, the biggest S3AN device is smaller than * 4 MiB. */ -static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) +static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) { - unsigned int offset; - unsigned int page; + u32 offset, page; offset = addr % nor->page_size; page = addr / nor->page_size; @@ -911,6 +910,14 @@ static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) return page | offset; } +static u32 spi_nor_convert_addr(struct spi_nor *nor, loff_t addr) +{ + if (!nor->params.convert_addr) + return addr; + + return nor->params.convert_addr(nor, addr); +} + /* * Initiate the erasure of a single sector */ @@ -918,8 +925,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) { int i; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); if (nor->erase) return nor->erase(nor, addr); @@ -2535,8 +2541,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, while (len) { loff_t addr = from; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); ret = spi_nor_read_data(nor, addr, len, buf); if (ret == 0) { @@ -2680,8 +2685,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, page_remain = min_t(size_t, nor->page_size - page_offset, len - i); - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); write_enable(nor); ret = spi_nor_write_data(nor, addr, page_remain, buf + i); @@ -2748,7 +2752,7 @@ static int s3an_nor_scan(struct spi_nor *nor) nor->mtd.erasesize = 8 * nor->page_size; } else { /* Flash in Default addressing mode */ - nor->flags |= SNOR_F_S3AN_ADDR_DEFAULT; + nor->params.convert_addr = s3an_convert_addr; } return 0; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index ea3bcac54dc2..35aad92a4ff8 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -237,13 +237,12 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB= BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), - SNOR_F_READY_XSR_RDY= BIT(4), - SNOR_F_USE_CLSR = BIT(5), - SNOR_F_BROKEN_RESET = BIT(6), - SNOR_F_4B_OPCODES = BIT(7), - SNOR_F_HAS_4BAIT= BIT(8), - SNOR_F_HAS_LOCK = BIT(9), + SNOR_F_READY_XSR_RDY= BIT(3), + SNOR_F_USE_CLSR = BIT(4), + SNOR_F_BROKEN_RESET = BIT(5), + SNOR_F_4B_OPCODES = BIT(6), + SNOR_F_HAS_4BAIT= BIT(7), + SNOR_F_HAS_LOCK = BIT(8), }; /** @@ -496,6 +495,9 @@ struct spi_nor_locking_ops { * Table. * @quad_enable: enables SPI NOR quad mode. * @set_4byte: puts the SPI NOR in 4 byte addressing mode. + * @convert_addr: converts an absolute address into something the flash + * will understand. Particularly useful when pagesize is + * not a power-of-2. * @locking_ops: SPI NOR locking methods. */ struct spi_nor_flash_parameter { @@ -510,6 +512,7 @@ struct spi_nor_flash_parameter { int (*quad_enable)(struct spi_nor *nor); int (*set_4byte)(struct spi_nor *nor,
[PATCH v3 10/20] mtd: spi-nor: Rework the SPI NOR lock/unlock logic
From: Boris Brezillon Add the SNOR_F_HAS_LOCK flag and set it when SPI_NOR_HAS_LOCK is set in the flash_info entry or when it's a Micron or ST flash. Move the locking hooks in a separate struct so that we have just one field to update when we change the locking implementation. Signed-off-by: Boris Brezillon [tudor.amba...@microchip.com: use ->default_init() hook, introduce spi_nor_late_init_params(), set ops in nor->params] Signed-off-by: Tudor Ambarus --- v3: no changes, clear_sr_bp() is handled in the last patch of the series. drivers/mtd/spi-nor/spi-nor.c | 50 --- include/linux/mtd/spi-nor.h | 23 ++-- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 235e82a121a1..3f997797fa9d 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1598,6 +1598,12 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) return stm_is_locked_sr(nor, ofs, len, status); } +static const struct spi_nor_locking_ops stm_locking_ops = { + .lock = stm_lock, + .unlock = stm_unlock, + .is_locked = stm_is_locked, +}; + static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct spi_nor *nor = mtd_to_spi_nor(mtd); @@ -1607,7 +1613,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_lock(nor, ofs, len); + ret = nor->params.locking_ops->lock(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); return ret; @@ -1622,7 +1628,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_unlock(nor, ofs, len); + ret = nor->params.locking_ops->unlock(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); return ret; @@ -1637,7 +1643,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ret) return ret; - ret = nor->flash_is_locked(nor, ofs, len); + ret = nor->params.locking_ops->is_locked(nor, ofs, len); spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); return ret; @@ -4148,6 +4154,7 @@ static void macronix_set_default_init(struct spi_nor *nor) static void st_micron_set_default_init(struct spi_nor *nor) { + nor->flags = SNOR_F_HAS_LOCK; nor->params.quad_enable = NULL; nor->params.set_4byte = st_micron_set_4byte; } @@ -4292,6 +4299,23 @@ static void spi_nor_info_init_params(struct spi_nor *nor) } /** + * spi_nor_late_init_params() - Late initialization of default flash parameters. + * @nor: pointer to a 'struct spi_nor' + * + * Used to set default flash parameters and settings when the ->default_init() + * hook or the SFDP parser let voids. + */ +static void spi_nor_late_init_params(struct spi_nor *nor) +{ + /* +* NOR protection support. When locking_ops are not provided, we pick +* the default ones. +*/ + if (nor->flags & SNOR_F_HAS_LOCK && !nor->params.locking_ops) + nor->params.locking_ops = _locking_ops; +} + +/** * spi_nor_init_params() - Initialize the flash's parameters and settings. * @nor: pointer to a 'struct spi-nor'. * @@ -4316,6 +4340,10 @@ static void spi_nor_info_init_params(struct spi_nor *nor) *Please not that there is a ->post_bfpt() fixup hook that can overwrite the *flash parameters and settings imediately after parsing the Basic Flash *Parameter Table. + * + * 4/ Late default flash parameters initialization, used when the + * ->default_init() hook or the SFDP parser do not set specific params. + * spi_nor_late_init_params() */ static void spi_nor_init_params(struct spi_nor *nor) { @@ -4326,6 +4354,8 @@ static void spi_nor_init_params(struct spi_nor *nor) if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && !(nor->info->flags & SPI_NOR_SKIP_SFDP)) spi_nor_sfdp_init_params(nor); + + spi_nor_late_init_params(nor); } static int spi_nor_select_read(struct spi_nor *nor, @@ -4707,6 +4737,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (info->flags & SPI_S3AN) nor->flags |= SNOR_F_READY_XSR_RDY; + if (info->flags & SPI_NOR_HAS_LOCK) + nor->flags |= SNOR_F_HAS_LOCK; + /* * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up * with the software protection bits set. @@ -4731,16 +4764,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, mtd->_read = spi_nor_read; mtd->_resume = spi_nor_resume; - /* NOR protection support for STmicro/Micron chips and similar */ - if (JEDEC_MFR(info) == SNOR_MFR_ST || -
[PATCH v3 14/20] mtd: spi_nor: Add a ->setup() method
From: Tudor Ambarus nor->params.setup() configures the SPI NOR memory. Useful for SPI NOR flashes that have peculiarities to the SPI NOR standard, e.g. different opcodes, specific address calculation, page size, etc. Right now the only user will be the S3AN chips, but other manufacturers can implement it if needed. Move spi_nor_setup() related code in order to avoid a forward declaration to spi_nor_default_setup(). Reviewed-by: Boris Brezillon Signed-off-by: Tudor Ambarus --- v3: collect R-b, rebase on previous commits drivers/mtd/spi-nor/spi-nor.c | 432 +- include/linux/mtd/spi-nor.h | 5 + 2 files changed, 226 insertions(+), 211 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b96a7066a36c..2aca56e07341 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4144,6 +4144,226 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } +static int spi_nor_select_read(struct spi_nor *nor, + u32 shared_hwcaps) +{ + int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_READ_MASK) - 1; + const struct spi_nor_read_command *read; + + if (best_match < 0) + return -EINVAL; + + cmd = spi_nor_hwcaps_read2cmd(BIT(best_match)); + if (cmd < 0) + return -EINVAL; + + read = >params.reads[cmd]; + nor->read_opcode = read->opcode; + nor->read_proto = read->proto; + + /* +* In the spi-nor framework, we don't need to make the difference +* between mode clock cycles and wait state clock cycles. +* Indeed, the value of the mode clock cycles is used by a QSPI +* flash memory to know whether it should enter or leave its 0-4-4 +* (Continuous Read / XIP) mode. +* eXecution In Place is out of the scope of the mtd sub-system. +* Hence we choose to merge both mode and wait state clock cycles +* into the so called dummy clock cycles. +*/ + nor->read_dummy = read->num_mode_clocks + read->num_wait_states; + return 0; +} + +static int spi_nor_select_pp(struct spi_nor *nor, +u32 shared_hwcaps) +{ + int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_PP_MASK) - 1; + const struct spi_nor_pp_command *pp; + + if (best_match < 0) + return -EINVAL; + + cmd = spi_nor_hwcaps_pp2cmd(BIT(best_match)); + if (cmd < 0) + return -EINVAL; + + pp = >params.page_programs[cmd]; + nor->program_opcode = pp->opcode; + nor->write_proto = pp->proto; + return 0; +} + +/** + * spi_nor_select_uniform_erase() - select optimum uniform erase type + * @map: the erase map of the SPI NOR + * @wanted_size: the erase type size to search for. Contains the value of + * info->sector_size or of the "small sector" size in case + * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined. + * + * Once the optimum uniform sector erase command is found, disable all the + * other. + * + * Return: pointer to erase type on success, NULL otherwise. + */ +static const struct spi_nor_erase_type * +spi_nor_select_uniform_erase(struct spi_nor_erase_map *map, +const u32 wanted_size) +{ + const struct spi_nor_erase_type *tested_erase, *erase = NULL; + int i; + u8 uniform_erase_type = map->uniform_erase_type; + + for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { + if (!(uniform_erase_type & BIT(i))) + continue; + + tested_erase = >erase_type[i]; + + /* +* If the current erase size is the one, stop here: +* we have found the right uniform Sector Erase command. +*/ + if (tested_erase->size == wanted_size) { + erase = tested_erase; + break; + } + + /* +* Otherwise, the current erase size is still a valid canditate. +* Select the biggest valid candidate. +*/ + if (!erase && tested_erase->size) + erase = tested_erase; + /* keep iterating to find the wanted_size */ + } + + if (!erase) + return NULL; + + /* Disable all other Sector Erase commands. */ + map->uniform_erase_type &= ~SNOR_ERASE_TYPE_MASK; + map->uniform_erase_type |= BIT(erase - map->erase_type); + return erase; +} + +static int spi_nor_select_erase(struct spi_nor *nor, u32 wanted_size) +{ + struct spi_nor_erase_map *map = >params.erase_map; + const struct spi_nor_erase_type *erase = NULL; + struct mtd_info *mtd = >mtd; + int i; + + /* +* The previous implementation handling Sector Erase commands assumed +
Re: [PATCH -next] ASoC: SOF: imx8: Fix return value check in imx8_probe()
On Mon, 2019-08-26 at 12:00 +, Wei Yongjun wrote: > In case of error, the function devm_ioremap_wc() returns NULL pointer > not ERR_PTR(). The IS_ERR() test in the return value check should be > replaced with NULL test. > > Fixes: 202acc565a1f ("ASoC: SOF: imx: Add i.MX8 HW support") > Signed-off-by: Wei Yongjun Good catch. Thanks! Reviewed-by: Daniel Baluta > --- > sound/soc/sof/imx/imx8.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c > index e502f584207f..263d4df35fe8 100644 > --- a/sound/soc/sof/imx/imx8.c > +++ b/sound/soc/sof/imx/imx8.c > @@ -296,10 +296,10 @@ static int imx8_probe(struct snd_sof_dev *sdev) > sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, > res.start, > res.end - > res.start + > 1); > - if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM])) { > + if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { > dev_err(sdev->dev, "failed to ioremap mem 0x%x size > 0x%x\n", > base, size); > - ret = PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]); > + ret = -ENOMEM; > goto exit_pdev_unregister; > } > sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; > > >
[PATCH v3 09/20] mtd: spi-nor: Create a ->set_4byte() method
From: Boris Brezillon The procedure used to enable 4 byte addressing mode depends on the NOR device, so let's provide a hook so that manufacturer specific handling can be implemented in a sane way. Signed-off-by: Boris Brezillon [tudor.amba...@microchip.com: use nor->params.set_4byte() instead of nor->set_4byte()] Signed-off-by: Tudor Ambarus --- v3: no changes drivers/mtd/spi-nor/spi-nor.c | 76 ++- include/linux/mtd/spi-nor.h | 2 ++ 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 1e7f8dc3457d..235e82a121a1 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -633,6 +633,17 @@ static int macronix_set_4byte(struct spi_nor *nor, bool enable) NULL, 0); } +static int st_micron_set_4byte(struct spi_nor *nor, bool enable) +{ + int ret; + + write_enable(nor); + ret = macronix_set_4byte(nor, enable); + write_disable(nor); + + return ret; +} + static int spansion_set_4byte(struct spi_nor *nor, bool enable) { nor->bouncebuf[0] = enable << 7; @@ -667,45 +678,24 @@ static int spi_nor_write_ear(struct spi_nor *nor, u8 ear) return nor->write_reg(nor, SPINOR_OP_WREAR, nor->bouncebuf, 1); } -/* Enable/disable 4-byte addressing mode. */ -static int set_4byte(struct spi_nor *nor, bool enable) +static int winbond_set_4byte(struct spi_nor *nor, bool enable) { - int status; - bool need_wren = false; - - switch (JEDEC_MFR(nor->info)) { - case SNOR_MFR_ST: - case SNOR_MFR_MICRON: - /* Some Micron need WREN command; all will accept it */ - need_wren = true; - /* fall through */ - case SNOR_MFR_MACRONIX: - case SNOR_MFR_WINBOND: - if (need_wren) - write_enable(nor); + int ret; - status = macronix_set_4byte(nor, enable); - if (need_wren) - write_disable(nor); + ret = macronix_set_4byte(nor, enable); + if (ret || enable) + return ret; - if (!status && !enable && - JEDEC_MFR(nor->info) == SNOR_MFR_WINBOND) { - /* -* On Winbond W25Q256FV, leaving 4byte mode causes -* the Extended Address Register to be set to 1, so all -* 3-byte-address reads come from the second 16M. -* We must clear the register to enable normal behavior. -*/ - write_enable(nor); - spi_nor_write_ear(nor, 0); - write_disable(nor); - } + /* +* On Winbond W25Q256FV, leaving 4byte mode causes the Extended Address +* Register to be set to 1, so all 3-byte-address reads come from the +* second 16M. We must clear the register to enable normal behavior. +*/ + write_enable(nor); + ret = spi_nor_write_ear(nor, 0); + write_disable(nor); - return status; - default: - /* Spansion style */ - return spansion_set_4byte(nor, enable); - } + return ret; } static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) @@ -4153,11 +4143,18 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, static void macronix_set_default_init(struct spi_nor *nor) { nor->params.quad_enable = macronix_quad_enable; + nor->params.set_4byte = macronix_set_4byte; } static void st_micron_set_default_init(struct spi_nor *nor) { nor->params.quad_enable = NULL; + nor->params.set_4byte = st_micron_set_4byte; +} + +static void winbond_set_default_init(struct spi_nor *nor) +{ + nor->params.set_4byte = winbond_set_4byte; } /** @@ -4178,6 +4175,10 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor) st_micron_set_default_init(nor); break; + case SNOR_MFR_WINBOND: + winbond_set_default_init(nor); + break; + default: break; } @@ -4222,6 +4223,7 @@ static void spi_nor_info_init_params(struct spi_nor *nor) /* Initialize legacy flash parameters and settings. */ params->quad_enable = spansion_quad_enable; + params->set_4byte = spansion_set_4byte; /* Set SPI NOR sizes. */ params->size = (u64)info->sector_size * info->n_sectors; @@ -4587,7 +4589,7 @@ static int spi_nor_init(struct spi_nor *nor) */ WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, "enabling reset hack; may not recover from unexpected reboots\n"); - set_4byte(nor, true); + nor->params.set_4byte(nor, true); } return 0; @@ -4611,7 +4613,7 @@ void
[PATCH v3 08/20] mtd: spi-nor: Split spi_nor_init_params()
From: Tudor Ambarus Add functions to delimit what the chunks of code do: static void spi_nor_init_params() { spi_nor_info_init_params() spi_nor_manufacturer_init_params() spi_nor_sfdp_init_params() } Add descriptions to all methods. spi_nor_init_params() becomes of type void, as all its children return void. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: rename spi_nor_legacy_init_params() to spi_nor_info_init_params() drivers/mtd/spi-nor/spi-nor.c | 83 --- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 2a239531704a..1e7f8dc3457d 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4186,7 +4186,34 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor) nor->info->fixups->default_init(nor); } -static int spi_nor_init_params(struct spi_nor *nor) +/** + * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings + * based on JESD216 SFDP standard. + * @nor: pointer to a 'struct spi-nor'. + * + * The method has a roll-back mechanism: in case the SFDP parsing fails, the + * legacy flash parameters and settings will be restored. + */ +static void spi_nor_sfdp_init_params(struct spi_nor *nor) +{ + struct spi_nor_flash_parameter sfdp_params; + + memcpy(_params, >params, sizeof(sfdp_params)); + + if (spi_nor_parse_sfdp(nor, _params)) { + nor->addr_width = 0; + nor->flags &= ~SNOR_F_4B_OPCODES; + } else { + memcpy(>params, _params, sizeof(nor->params)); + } +} + +/** + * spi_nor_info_init_params() - Initialize the flash's parameters and settings + * based on nor->info data. + * @nor: pointer to a 'struct spi-nor'. + */ +static void spi_nor_info_init_params(struct spi_nor *nor) { struct spi_nor_flash_parameter *params = >params; struct spi_nor_erase_map *map = >erase_map; @@ -4260,25 +4287,43 @@ static int spi_nor_init_params(struct spi_nor *nor) spi_nor_set_erase_type(>erase_type[i], info->sector_size, SPINOR_OP_SE); spi_nor_init_uniform_erase_map(map, erase_mask, params->size); +} +/** + * spi_nor_init_params() - Initialize the flash's parameters and settings. + * @nor: pointer to a 'struct spi-nor'. + * + * The flash parameters and settings are initialized based on a sequence of + * calls that are ordered by priority: + * + * 1/ Default flash parameters initialization. The initializations are done + *based on nor->info data: + * spi_nor_info_init_params() + * + * which can be overwritten by: + * 2/ Manufacturer flash parameters initialization. The initializations are + *done based on MFR register, or when the decisions can not be done solely + *based on MFR, by using specific flash_info tweeks, ->default_init(): + * spi_nor_manufacturer_init_params() + * + * which can be overwritten by: + * 3/ SFDP flash parameters initialization. JESD216 SFDP is a standard and + *should be more accurate that the above. + * spi_nor_sfdp_init_params() + * + *Please not that there is a ->post_bfpt() fixup hook that can overwrite the + *flash parameters and settings imediately after parsing the Basic Flash + *Parameter Table. + */ +static void spi_nor_init_params(struct spi_nor *nor) +{ + spi_nor_info_init_params(nor); spi_nor_manufacturer_init_params(nor); - if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && - !(info->flags & SPI_NOR_SKIP_SFDP)) { - struct spi_nor_flash_parameter sfdp_params; - - memcpy(_params, params, sizeof(sfdp_params)); - - if (spi_nor_parse_sfdp(nor, _params)) { - nor->addr_width = 0; - nor->flags &= ~SNOR_F_4B_OPCODES; - } else { - memcpy(params, _params, sizeof(*params)); - } - } - - return 0; + if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && + !(nor->info->flags & SPI_NOR_SKIP_SFDP)) + spi_nor_sfdp_init_params(nor); } static int spi_nor_select_read(struct spi_nor *nor, @@ -4670,10 +4715,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->info->flags & SPI_NOR_HAS_LOCK) nor->clear_sr_bp = spi_nor_clear_sr_bp; - /* Parse the Serial Flash Discoverable Parameters table. */ - ret = spi_nor_init_params(nor); - if (ret) - return ret; + /* Init flash parameters based on flash_info struct and SFDP */ + spi_nor_init_params(nor); if (!mtd->name) mtd->name = dev_name(dev); -- 2.9.5
[PATCH v3 07/20] mtd: spi_nor: Move manufacturer quad_enable() in ->default_init()
From: Tudor Ambarus The goal is to move the quad_enable manufacturer specific init in the nor->manufacturer->fixups->default_init() The legacy quad_enable() implementation is spansion_quad_enable(), select this method by default. Set specific manufacturer fixups->default_init() hooks to overwrite the default quad_enable() implementation when needed. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: collect R-b drivers/mtd/spi-nor/spi-nor.c | 48 ++- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 3dbbfe34d1d2..2a239531704a 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4150,13 +4150,38 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } +static void macronix_set_default_init(struct spi_nor *nor) +{ + nor->params.quad_enable = macronix_quad_enable; +} + +static void st_micron_set_default_init(struct spi_nor *nor) +{ + nor->params.quad_enable = NULL; +} + /** * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and - * settings based on ->default_init() hook. + * settings based on MFR register and ->default_init() hook. * @nor: pointer to a 'struct spi-nor'. */ static void spi_nor_manufacturer_init_params(struct spi_nor *nor) { + /* Init flash parameters based on MFR */ + switch (JEDEC_MFR(nor->info)) { + case SNOR_MFR_MACRONIX: + macronix_set_default_init(nor); + break; + + case SNOR_MFR_ST: + case SNOR_MFR_MICRON: + st_micron_set_default_init(nor); + break; + + default: + break; + } + if (nor->info->fixups && nor->info->fixups->default_init) nor->info->fixups->default_init(nor); } @@ -4168,6 +4193,9 @@ static int spi_nor_init_params(struct spi_nor *nor) const struct flash_info *info = nor->info; u8 i, erase_mask; + /* Initialize legacy flash parameters and settings. */ + params->quad_enable = spansion_quad_enable; + /* Set SPI NOR sizes. */ params->size = (u64)info->sector_size * info->n_sectors; params->page_size = info->page_size; @@ -4233,24 +4261,6 @@ static int spi_nor_init_params(struct spi_nor *nor) SPINOR_OP_SE); spi_nor_init_uniform_erase_map(map, erase_mask, params->size); - /* Select the procedure to set the Quad Enable bit. */ - if (params->hwcaps.mask & (SNOR_HWCAPS_READ_QUAD | - SNOR_HWCAPS_PP_QUAD)) { - switch (JEDEC_MFR(info)) { - case SNOR_MFR_MACRONIX: - params->quad_enable = macronix_quad_enable; - break; - - case SNOR_MFR_ST: - case SNOR_MFR_MICRON: - break; - - default: - /* Kept only for backward compatibility purpose. */ - params->quad_enable = spansion_quad_enable; - break; - } - } spi_nor_manufacturer_init_params(nor); -- 2.9.5
[PATCH v3 04/20] mtd: spi-nor: Move erase_map to 'struct spi_nor_flash_parameter'
From: Tudor Ambarus All flash parameters and settings should reside inside 'struct spi_nor_flash_parameter'. Move the SMPT parsed erase map from 'struct spi_nor' to 'struct spi_nor_flash_parameter'. Please note that there is a roll-back mechanism for the flash parameter and settings, for cases when SFDP parser fails. The SFDP parser receives a Stack allocated copy of nor->params, called sfdp_params, and uses it to retrieve the serial flash discoverable parameters. JESD216 SFDP is a standard and has a higher priority than the default initialized flash parameters, so will overwrite the sfdp_params data when needed. All SFDP code uses the local copy of nor->params, that will overwrite it in the end, if the parser succeds. Saving and restoring the nor->params.erase_map is no longer needed, since the SFDP code does not touch it. Signed-off-by: Tudor Ambarus --- v3: Collect R-b drivers/mtd/spi-nor/spi-nor.c | 40 +--- include/linux/mtd/spi-nor.h | 8 +--- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index effda372cb33..9dd6cd8cd13c 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -600,7 +600,7 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); if (!spi_nor_has_uniform_erase(nor)) { - struct spi_nor_erase_map *map = >erase_map; + struct spi_nor_erase_map *map = >params.erase_map; struct spi_nor_erase_type *erase; int i; @@ -1133,7 +1133,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor, struct list_head *erase_list, u64 addr, u32 len) { - const struct spi_nor_erase_map *map = >erase_map; + const struct spi_nor_erase_map *map = >params.erase_map; const struct spi_nor_erase_type *erase, *prev_erase = NULL; struct spi_nor_erase_region *region; struct spi_nor_erase_command *cmd = NULL; @@ -3328,7 +3328,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, struct spi_nor_flash_parameter *params) { - struct spi_nor_erase_map *map = >erase_map; + struct spi_nor_erase_map *map = >erase_map; struct spi_nor_erase_type *erase_type = map->erase_type; struct sfdp_bfpt bfpt; size_t len; @@ -3409,7 +3409,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, * Erase Types defined in the bfpt table. */ erase_mask = 0; - memset(>erase_map, 0, sizeof(nor->erase_map)); + memset(>erase_map, 0, sizeof(params->erase_map)); for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) { const struct sfdp_bfpt_erase *er = _bfpt_erases[i]; u32 erasesize; @@ -3684,14 +3684,18 @@ spi_nor_region_check_overlay(struct spi_nor_erase_region *region, /** * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map * @nor: pointer to a 'struct spi_nor' + * @params: pointer to a duplicate 'struct spi_nor_flash_parameter' that is + * used for storing SFDP parsed data * @smpt: pointer to the sector map parameter table * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, - const u32 *smpt) +static int +spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, + struct spi_nor_flash_parameter *params, + const u32 *smpt) { - struct spi_nor_erase_map *map = >erase_map; + struct spi_nor_erase_map *map = >erase_map; struct spi_nor_erase_type *erase = map->erase_type; struct spi_nor_erase_region *region; u64 offset; @@ -3770,6 +3774,8 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, * spi_nor_parse_smpt() - parse Sector Map Parameter Table * @nor: pointer to a 'struct spi_nor' * @smpt_header: sector map parameter table header + * @params:pointer to a duplicate 'struct spi_nor_flash_parameter' + * that is used for storing SFDP parsed data * * This table is optional, but when available, we parse it to identify the * location and size of sectors within the main data array of the flash memory @@ -3778,7 +3784,8 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, * Return: 0 on success, -errno otherwise. */ static int spi_nor_parse_smpt(struct spi_nor *nor, - const struct sfdp_parameter_header *smpt_header) + const struct sfdp_parameter_header *smpt_header, +
Re: [PATCH v2 00/20] Initial support for Marvell MMP3 SoC
On Fri, 2019-08-23 at 10:42 +0100, Marc Zyngier wrote: > On 23/08/2019 08:21, Lubomir Rintel wrote: > > On Thu, 2019-08-22 at 11:31 +0100, Marc Zyngier wrote: > > > On 22/08/2019 10:26, Lubomir Rintel wrote: > > > > Hi, > > > > > > > > this is a second spin of a patch set that adds support for the Marvell > > > > MMP3 processor. MMP3 is used in OLPC XO-4 laptops, Panasonic Toughpad > > > > FZ-A1 tablet and Dell Wyse 3020 Tx0D thin clients. > > > > > > > > Compared to v1, there's a handful of fixes in response to reviews. Patch > > > > 02/20 is new. Details in individual patches. > > > > > > > > Apart from the adjustments in mach-mmp/, the patch makes necessary > > > > changes to the irqchip driver and adds an USB2 PHY driver. The latter > > > > has a dependency on the mach-mmp/ changes, so it can't be submitted > > > > separately. > > > > > > > > The patch set has been tested to work on Wyse Tx0D and not ruin MMP2 > > > > support on XO-1.75. > > > > > > How do you want this series to be merged? I'm happy to take the irqchip > > > related patches as well as the corresponding DT change (once reviewed) > > > through my tree. > > > > I was hoping for the Arm SoC tree, because there are some dependencies > > (MMP3 USB PHY depends on MMP3 SoC). > > > > That said, the irqchip patches are rather independent and the only > > downside of them going in via a different tree will be that the other > > tree that will lack them won't boot on MMP3 (things will compile > > though). I don't know if that's okay. What's typically done in cases > > like these? > > I usually take the irqchip patches that can be built standalone (without > dependency on header files, for example). If you want them to go via > another tree, stick my > > Acked-by: Marc Zyngier > > on patches #6 through #9. Actually, please go ahead and pick the irqchip patches into your tree. The rest of the patch set may need a couple more spins, and it will be nice if it gets shorter. Thank you Lubo
Re: [PATCH v3] i2c: axxia: support slave mode
Hi! On 19/08/2019 11:07, Adamski, Krzysztof (Nokia - PL/Wroclaw) wrote: > This device contains both master and slave controllers which can be > enabled simultaneously. Both controllers share the same SDA/SCL lines > and interrupt source but has separate control and status registers. > Controllers also works in loopback mode - slave device can communicate > with its own master controller internally. The controller can handle up > to two addresses, both of which may be 10 bit. Most of the logic > (sending (N)ACK, handling repeated start or switching between > write/read) is handled automatically which makes working with this > controller quite easy. > > For simplicity, this patch adds basic support, limiting to only one > slave address. Support for the 2nd device may be added in the future. > > Note that synchronize_irq() is used to ensure any running slave interrupt > is finished to make sure slave i2c_client structure can be safely used > by i2c_slave_event. Reviewed-by: Alexander Sverdlin > Signed-off-by: Krzysztof Adamski > --- > Changes in v3: > - Fixed braces for one-line if bodies > > Changes in v2: > - Reduced the number of dev_dbg messages. > > drivers/i2c/busses/Kconfig | 1 + > drivers/i2c/busses/i2c-axxia.c | 152 +++-- > 2 files changed, 145 insertions(+), 8 deletions(-) > > diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig > index 69f19312a574..b8262301c86d 100644 > --- a/drivers/i2c/busses/Kconfig > +++ b/drivers/i2c/busses/Kconfig > @@ -429,6 +429,7 @@ config I2C_AXXIA > tristate "Axxia I2C controller" > depends on ARCH_AXXIA || COMPILE_TEST > default ARCH_AXXIA > + select I2C_SLAVE > help > Say yes if you want to support the I2C bus on Axxia platforms. > > diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c > index ff3142b15cab..0214daa913ff 100644 > --- a/drivers/i2c/busses/i2c-axxia.c > +++ b/drivers/i2c/busses/i2c-axxia.c > @@ -77,6 +77,40 @@ >MST_STATUS_IP) > #define MST_TX_BYTES_XFRD0x50 > #define MST_RX_BYTES_XFRD0x54 > +#define SLV_ADDR_DEC_CTL 0x58 > +#define SLV_ADDR_DEC_GCE BIT(0) /* ACK to General Call Address from own > master (loopback) */ > +#define SLV_ADDR_DEC_OGCE BIT(1) /* ACK to General Call Address from > external masters */ > +#define SLV_ADDR_DEC_SA1E BIT(2) /* ACK to addr_1 enabled */ > +#define SLV_ADDR_DEC_SA1M BIT(3) /* 10-bit addressing for addr_1 enabled > */ > +#define SLV_ADDR_DEC_SA2E BIT(4) /* ACK to addr_2 enabled */ > +#define SLV_ADDR_DEC_SA2M BIT(5) /* 10-bit addressing for addr_2 enabled > */ > +#define SLV_ADDR_1 0x5c > +#define SLV_ADDR_2 0x60 > +#define SLV_RX_CTL 0x64 > +#define SLV_RX_ACSA1 BIT(0) /* Generate ACK for writes to > addr_1 */ > +#define SLV_RX_ACSA2 BIT(1) /* Generate ACK for writes to > addr_2 */ > +#define SLV_RX_ACGCA BIT(2) /* ACK data phase transfers to > General Call Address */ > +#define SLV_DATA 0x68 > +#define SLV_RX_FIFO 0x6c > +#define SLV_FIFO_DV1 BIT(0) /* Data Valid for addr_1 */ > +#define SLV_FIFO_DV2 BIT(1) /* Data Valid for addr_2 */ > +#define SLV_FIFO_ASBIT(2) /* (N)ACK Sent */ > +#define SLV_FIFO_TNAK BIT(3) /* Timeout NACK */ > +#define SLV_FIFO_STRC BIT(4) /* First byte after start > condition received */ > +#define SLV_FIFO_RSC BIT(5) /* Repeated Start Condition */ > +#define SLV_FIFO_STPC BIT(6) /* Stop Condition */ > +#define SLV_FIFO_DV(SLV_FIFO_DV1 | SLV_FIFO_DV2) > +#define SLV_INT_ENABLE 0x70 > +#define SLV_INT_STATUS 0x74 > +#define SLV_STATUS_RFH BIT(0) /* FIFO service */ > +#define SLV_STATUS_WTC BIT(1) /* Write transfer complete */ > +#define SLV_STATUS_SRS1BIT(2) /* Slave read from addr 1 */ > +#define SLV_STATUS_SRRS1 BIT(3) /* Repeated start from addr 1 */ > +#define SLV_STATUS_SRND1 BIT(4) /* Read request not following start > condition */ > +#define SLV_STATUS_SRC1BIT(5) /* Read canceled */ > +#define SLV_STATUS_SRAT1 BIT(6) /* Slave Read timed out */ > +#define SLV_STATUS_SRDRE1 BIT(7) /* Data written after timed out */ > +#define SLV_READ_DUMMY 0x78 > #define SCL_HIGH_PERIOD 0x80 > #define SCL_LOW_PERIOD 0x84 > #define SPIKE_FLTR_LEN 0x88 > @@ -111,6 +145,8 @@ struct axxia_i2c_dev { > struct clk *i2c_clk; > u32 bus_clk_rate; > bool last; > + struct i2c_client *slave; > + int irq; > }; > > static void i2c_int_disable(struct axxia_i2c_dev *idev, u32 mask) > @@ -276,13 +312,65 @@ static int axxia_i2c_fill_tx_fifo(struct axxia_i2c_dev > *idev) > return ret; > } > > +static void
[PATCH v3 02/20] mtd: spi-nor: Use nor->params
From: Tudor Ambarus The Flash parameters and settings are now stored in 'struct spi_nor'. Use this instead of the stack allocated params. Few functions stop passing pointer to params, as they can get it from 'struct spi_nor'. spi_nor_parse_sfdp() and children will keep passing pointer to params because of the roll-back mechanism: in case the parsing of SFDP fails, the legacy flash parameter and settings will be restored. Zeroing params is no longer needed because all SPI NOR users kzalloc 'struct spi_nor'. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: collect R-b drivers/mtd/spi-nor/spi-nor.c | 46 ++- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index d35dc6a97521..e9b9cd70a999 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -2974,16 +2974,13 @@ static int spi_nor_spimem_check_pp(struct spi_nor *nor, * spi_nor_spimem_adjust_hwcaps - Find optimal Read/Write protocol *based on SPI controller capabilities * @nor:pointer to a 'struct spi_nor' - * @params: pointer to the 'struct spi_nor_flash_parameter' - * representing SPI NOR flash capabilities * @hwcaps: pointer to resulting capabilities after adjusting * according to controller and flash's capability */ static void -spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, -const struct spi_nor_flash_parameter *params, -u32 *hwcaps) +spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps) { + struct spi_nor_flash_parameter *params = >params; unsigned int cap; /* DTR modes are not supported yet, mask them all. */ @@ -4129,16 +4126,13 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } -static int spi_nor_init_params(struct spi_nor *nor, - struct spi_nor_flash_parameter *params) +static int spi_nor_init_params(struct spi_nor *nor) { + struct spi_nor_flash_parameter *params = >params; struct spi_nor_erase_map *map = >erase_map; const struct flash_info *info = nor->info; u8 i, erase_mask; - /* Set legacy flash parameters as default. */ - memset(params, 0, sizeof(*params)); - /* Set SPI NOR sizes. */ params->size = (u64)info->sector_size * info->n_sectors; params->page_size = info->page_size; @@ -4255,7 +4249,6 @@ static int spi_nor_init_params(struct spi_nor *nor, } static int spi_nor_select_read(struct spi_nor *nor, - const struct spi_nor_flash_parameter *params, u32 shared_hwcaps) { int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_READ_MASK) - 1; @@ -4268,7 +4261,7 @@ static int spi_nor_select_read(struct spi_nor *nor, if (cmd < 0) return -EINVAL; - read = >reads[cmd]; + read = >params.reads[cmd]; nor->read_opcode = read->opcode; nor->read_proto = read->proto; @@ -4287,7 +4280,6 @@ static int spi_nor_select_read(struct spi_nor *nor, } static int spi_nor_select_pp(struct spi_nor *nor, -const struct spi_nor_flash_parameter *params, u32 shared_hwcaps) { int cmd, best_match = fls(shared_hwcaps & SNOR_HWCAPS_PP_MASK) - 1; @@ -4300,7 +4292,7 @@ static int spi_nor_select_pp(struct spi_nor *nor, if (cmd < 0) return -EINVAL; - pp = >page_programs[cmd]; + pp = >params.page_programs[cmd]; nor->program_opcode = pp->opcode; nor->write_proto = pp->proto; return 0; @@ -4407,9 +4399,9 @@ static int spi_nor_select_erase(struct spi_nor *nor, u32 wanted_size) } static int spi_nor_setup(struct spi_nor *nor, -const struct spi_nor_flash_parameter *params, const struct spi_nor_hwcaps *hwcaps) { + struct spi_nor_flash_parameter *params = >params; u32 ignored_mask, shared_mask; bool enable_quad_io; int err; @@ -4426,7 +4418,7 @@ static int spi_nor_setup(struct spi_nor *nor, * need to discard some of them based on what the SPI * controller actually supports (using spi_mem_supports_op()). */ - spi_nor_spimem_adjust_hwcaps(nor, params, _mask); + spi_nor_spimem_adjust_hwcaps(nor, _mask); } else { /* * SPI n-n-n protocols are not supported when the SPI @@ -4442,7 +4434,7 @@ static int spi_nor_setup(struct spi_nor *nor, } /* Select the (Fast) Read command. */ - err = spi_nor_select_read(nor, params, shared_mask); + err = spi_nor_select_read(nor, shared_mask); if (err) { dev_err(nor->dev,
[PATCH v3 01/20] mtd: spi-nor: Regroup flash parameter and settings
From: Tudor Ambarus The scope is to move all [FLASH-SPECIFIC] parameters and settings from 'struct spi_nor' to 'struct spi_nor_flash_parameter'. 'struct spi_nor_flash_parameter' describes the hardware capabilities and associated settings of the SPI NOR flash memory. It includes legacy flash parameters and settings that can be overwritten by the spi_nor_fixups hooks, or dynamically when parsing the JESD216 Serial Flash Discoverable Parameters (SFDP) tables. All SFDP params and settings will fit inside 'struct spi_nor_flash_parameter'. Move spi_nor_hwcaps related code to avoid forward declarations. Add a forward declaration that we can't avoid: 'struct spi_nor' will be used in 'struct spi_nor_flash_parameter'. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: collect R-b drivers/mtd/spi-nor/spi-nor.c | 65 include/linux/mtd/spi-nor.h | 239 +- 2 files changed, 164 insertions(+), 140 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 0597cb8257b0..d35dc6a97521 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -40,71 +40,6 @@ #define SPI_NOR_MAX_ID_LEN 6 #define SPI_NOR_MAX_ADDR_WIDTH 4 -struct spi_nor_read_command { - u8 num_mode_clocks; - u8 num_wait_states; - u8 opcode; - enum spi_nor_protocol proto; -}; - -struct spi_nor_pp_command { - u8 opcode; - enum spi_nor_protocol proto; -}; - -enum spi_nor_read_command_index { - SNOR_CMD_READ, - SNOR_CMD_READ_FAST, - SNOR_CMD_READ_1_1_1_DTR, - - /* Dual SPI */ - SNOR_CMD_READ_1_1_2, - SNOR_CMD_READ_1_2_2, - SNOR_CMD_READ_2_2_2, - SNOR_CMD_READ_1_2_2_DTR, - - /* Quad SPI */ - SNOR_CMD_READ_1_1_4, - SNOR_CMD_READ_1_4_4, - SNOR_CMD_READ_4_4_4, - SNOR_CMD_READ_1_4_4_DTR, - - /* Octal SPI */ - SNOR_CMD_READ_1_1_8, - SNOR_CMD_READ_1_8_8, - SNOR_CMD_READ_8_8_8, - SNOR_CMD_READ_1_8_8_DTR, - - SNOR_CMD_READ_MAX -}; - -enum spi_nor_pp_command_index { - SNOR_CMD_PP, - - /* Quad SPI */ - SNOR_CMD_PP_1_1_4, - SNOR_CMD_PP_1_4_4, - SNOR_CMD_PP_4_4_4, - - /* Octal SPI */ - SNOR_CMD_PP_1_1_8, - SNOR_CMD_PP_1_8_8, - SNOR_CMD_PP_8_8_8, - - SNOR_CMD_PP_MAX -}; - -struct spi_nor_flash_parameter { - u64 size; - u32 page_size; - - struct spi_nor_hwcaps hwcaps; - struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; - struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; - - int (*quad_enable)(struct spi_nor *nor); -}; - struct sfdp_parameter_header { u8 id_lsb; u8 minor; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 3075ac73b171..77ba692d9348 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -334,6 +334,165 @@ struct spi_nor_erase_map { }; /** + * struct spi_nor_hwcaps - Structure for describing the hardware capabilies + * supported by the SPI controller (bus master). + * @mask: the bitmask listing all the supported hw capabilies + */ +struct spi_nor_hwcaps { + u32 mask; +}; + +/* + *(Fast) Read capabilities. + * MUST be ordered by priority: the higher bit position, the higher priority. + * As a matter of performances, it is relevant to use Octal SPI protocols first, + * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly + * (Slow) Read. + */ +#define SNOR_HWCAPS_READ_MASK GENMASK(14, 0) +#define SNOR_HWCAPS_READ BIT(0) +#define SNOR_HWCAPS_READ_FAST BIT(1) +#define SNOR_HWCAPS_READ_1_1_1_DTR BIT(2) + +#define SNOR_HWCAPS_READ_DUAL GENMASK(6, 3) +#define SNOR_HWCAPS_READ_1_1_2 BIT(3) +#define SNOR_HWCAPS_READ_1_2_2 BIT(4) +#define SNOR_HWCAPS_READ_2_2_2 BIT(5) +#define SNOR_HWCAPS_READ_1_2_2_DTR BIT(6) + +#define SNOR_HWCAPS_READ_QUAD GENMASK(10, 7) +#define SNOR_HWCAPS_READ_1_1_4 BIT(7) +#define SNOR_HWCAPS_READ_1_4_4 BIT(8) +#define SNOR_HWCAPS_READ_4_4_4 BIT(9) +#define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) + +#define SNOR_HWCAPS_READ_OCTAL GENMASK(14, 11) +#define SNOR_HWCAPS_READ_1_1_8 BIT(11) +#define SNOR_HWCAPS_READ_1_8_8 BIT(12) +#define SNOR_HWCAPS_READ_8_8_8 BIT(13) +#define SNOR_HWCAPS_READ_1_8_8_DTR BIT(14) + +/* + * Page Program capabilities. + * MUST be ordered by priority: the higher bit position, the higher priority. + * Like (Fast) Read capabilities, Octal/Quad SPI protocols are preferred to the + * legacy SPI 1-1-1 protocol. + * Note that Dual Page Programs are not supported because there is no existing + *
[PATCH v3 05/20] mtd: spi-nor: Add default_init() hook to tweak flash parameters
From: Tudor Ambarus As of now, the flash parameters initialization logic is as following: a/ default flash parameters init in spi_nor_init_params() b/ manufacturer specific flash parameters updates, split across entire spi-nor core code c/ flash parameters updates based on SFDP tables d/ post BFPT flash parameter updates In the quest of removing the manufacturer specific code from the spi-nor core, we want to impose a timeline/priority on how the flash parameters are updated. The following sequence of calls is pursued: 1/ spi-nor core parameters init based on 'flash_info' struct: spi_nor_info_init_params() which can be overwritten by: 2/ MFR-based manufacturer flash parameters init: nor->manufacturer->fixups->default_init() which can be overwritten by: 3/ specific flash_info tweeks done when decisions can not be done just on MFR: nor->info->fixups->default_init() which can be overwritten by: 4/ SFDP tables flash parameters init - SFDP knows better: spi_nor_sfdp_init_params() which can be overwritten by: 5/ post SFDP tables flash parameters updates - in case manufacturers get the serial flash tables wrong or incomplete. nor->info->fixups->post_sfdp() The later can be extended to nor->manufacturer->fixups->post_sfdp() if needed. This patch opens doors for steps 2/ and 3/. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: reword description drivers/mtd/spi-nor/spi-nor.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 9dd6cd8cd13c..8fd60e1eebd2 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -154,12 +154,16 @@ struct sfdp_bfpt { /** * struct spi_nor_fixups - SPI NOR fixup hooks + * @default_init: called after default flash parameters init. Used to tweak + *flash parameters when information provided by the flash_info + *table is incomplete or wrong. * @post_bfpt: called after the BFPT table has been parsed * * Those hooks can be used to tweak the SPI NOR configuration when the SFDP * table is broken or not available. */ struct spi_nor_fixups { + void (*default_init)(struct spi_nor *nor); int (*post_bfpt)(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt, @@ -4133,6 +4137,17 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, return err; } +/** + * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and + * settings based on ->default_init() hook. + * @nor: pointer to a 'struct spi-nor'. + */ +static void spi_nor_manufacturer_init_params(struct spi_nor *nor) +{ + if (nor->info->fixups && nor->info->fixups->default_init) + nor->info->fixups->default_init(nor); +} + static int spi_nor_init_params(struct spi_nor *nor) { struct spi_nor_flash_parameter *params = >params; @@ -4233,6 +4248,8 @@ static int spi_nor_init_params(struct spi_nor *nor) params->quad_enable = info->quad_enable; } + spi_nor_manufacturer_init_params(nor); + if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && !(info->flags & SPI_NOR_SKIP_SFDP)) { struct spi_nor_flash_parameter sfdp_params; -- 2.9.5
[PATCH v3 03/20] mtd: spi-nor: Drop quad_enable() from 'struct spi-nor'
From: Tudor Ambarus All flash parameters and settings should reside inside 'struct spi_nor_flash_parameter'. Drop the local copy of quad_enable() and use the one from 'struct spi_nor_flash_parameter'. Signed-off-by: Tudor Ambarus Reviewed-by: Boris Brezillon --- v3: Collect R-b drivers/mtd/spi-nor/spi-nor.c | 40 +++- include/linux/mtd/spi-nor.h | 2 -- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index e9b9cd70a999..effda372cb33 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -4403,7 +4403,6 @@ static int spi_nor_setup(struct spi_nor *nor, { struct spi_nor_flash_parameter *params = >params; u32 ignored_mask, shared_mask; - bool enable_quad_io; int err; /* @@ -4457,23 +4456,33 @@ static int spi_nor_setup(struct spi_nor *nor, return err; } - /* Enable Quad I/O if needed. */ - enable_quad_io = (spi_nor_get_protocol_width(nor->read_proto) == 4 || - spi_nor_get_protocol_width(nor->write_proto) == 4); - if (enable_quad_io && params->quad_enable) - nor->quad_enable = params->quad_enable; - else - nor->quad_enable = NULL; - return 0; } +/** + * spi_nor_quad_enable() - enable Quad I/O if needed. + * @nor:pointer to a 'struct spi_nor' + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_quad_enable(struct spi_nor *nor) +{ + if (!nor->params.quad_enable) + return 0; + + if (!(spi_nor_get_protocol_width(nor->read_proto) == 4 || + spi_nor_get_protocol_width(nor->write_proto) == 4)) + return 0; + + return nor->params.quad_enable(nor); +} + static int spi_nor_init(struct spi_nor *nor) { int err; if (nor->clear_sr_bp) { - if (nor->quad_enable == spansion_quad_enable) + if (nor->params.quad_enable == spansion_quad_enable) nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp; err = nor->clear_sr_bp(nor); @@ -4484,12 +4493,10 @@ static int spi_nor_init(struct spi_nor *nor) } } - if (nor->quad_enable) { - err = nor->quad_enable(nor); - if (err) { - dev_err(nor->dev, "quad mode not supported\n"); - return err; - } + err = spi_nor_quad_enable(nor); + if (err) { + dev_err(nor->dev, "quad mode not supported\n"); + return err; } if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) { @@ -4706,7 +4713,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, * - select op codes for (Fast) Read, Page Program and Sector Erase. * - set the number of dummy cycles (mode cycles + wait states). * - set the SPI protocols for register and memory accesses. -* - set the Quad Enable bit if needed (required by SPI x-y-4 protos). */ ret = spi_nor_setup(nor, hwcaps); if (ret) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 77ba692d9348..17787238f0e9 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -535,7 +535,6 @@ struct flash_info; * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is * completely locked - * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @clear_sr_bp: [FLASH-SPECIFIC] clears the Block Protection Bits from * the SPI NOR Status Register. * @params:[FLASH-SPECIFIC] SPI-NOR flash parameters and settings. @@ -579,7 +578,6 @@ struct spi_nor { int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*quad_enable)(struct spi_nor *nor); int (*clear_sr_bp)(struct spi_nor *nor); struct spi_nor_flash_parameter params; -- 2.9.5
[PATCH v3 00/20] mtd: spi-nor: move manuf out of the core
From: Tudor Ambarus v3: - Drop patches: "mtd: spi-nor: Move clear_sr_bp() to 'struct spi_nor_flash_parameter'" "mtd: spi-nor: Rework the disabling of block write protection" and replace them with the RFC patch: "mtd: spi-nor: Rework the disabling of block write protection" - rename spi_nor_legacy_init_params() to spi_nor_info_init_params() - rebase patches and send them all in a single patch set. v2: - addressed all the comments - all flash parameters and settings are now set in 'struct spi_nor_flash_parameter', for a clearer separation between the SPI NOR layer and the flash params. The scope of the "mtd: spi-nor: move manuf out of the core" batches, is to move all manufacturer specific code out of the spi-nor core. In the quest of removing the manufacturer specific code from the spi-nor core, we want to impose a timeline/priority on how the flash parameters are updated. As of now. the flash parameters initialization logic is as following: a/ default flash parameters init in spi_nor_init_params() b/ manufacturer specific flash parameters updates, split across entire spi-nor core code c/ flash parameters updates based on SFDP tables d/ post BFPT flash parameter updates With the "mtd: spi-nor: move manuf out of the core" batches, we want to impose the following sequence of calls: 1/ spi-nor core legacy flash parameters init: spi_nor_default_init_params() 2/ MFR-based manufacturer flash parameters init: nor->manufacturer->fixups->default_init() 3/ specific flash_info tweeks done when decisions can not be done just on MFR: nor->info->fixups->default_init() 4/ SFDP tables flash parameters init - SFDP knows better: spi_nor_sfdp_init_params() 5/ post SFDP tables flash parameters updates - in case manufacturers get the serial flash tables wrong or incomplete. nor->info->fixups->post_sfdp() The later can be extended to nor->manufacturer->fixups->post_sfdp() if needed. Setting of flash parameters will no longer be spread interleaved across the spi-nor core, there will be a clear separation on who and when will update the flash parameters. Tested on sst26vf064b with atmel-quadspi SPIMEM driver. Boris Brezillon (7): mtd: spi-nor: Add a default_init() fixup hook for gd25q256 mtd: spi-nor: Create a ->set_4byte() method mtd: spi-nor: Rework the SPI NOR lock/unlock logic mtd: spi-nor: Add post_sfdp() hook to tweak flash config mtd: spi-nor: Add spansion_post_sfdp_fixups() mtd: spi-nor: Add a ->convert_addr() method mtd: spi-nor: Add the SPI_NOR_XSR_RDY flag Tudor Ambarus (13): mtd: spi-nor: Regroup flash parameter and settings mtd: spi-nor: Use nor->params mtd: spi-nor: Drop quad_enable() from 'struct spi-nor' mtd: spi-nor: Move erase_map to 'struct spi_nor_flash_parameter' mtd: spi-nor: Add default_init() hook to tweak flash parameters mtd: spi_nor: Move manufacturer quad_enable() in ->default_init() mtd: spi-nor: Split spi_nor_init_params() mtd: spi_nor: Add a ->setup() method mtd: spi-nor: Add s3an_post_sfdp_fixups() mtd: spi-nor: Bring flash params init together mtd: spi_nor: Introduce spi_nor_set_addr_width() mtd: spi-nor: Introduce spi_nor_get_flash_info() mtd: spi-nor: Rework the disabling of block write protection drivers/mtd/spi-nor/spi-nor.c | 1304 +++-- include/linux/mtd/spi-nor.h | 298 +++--- 2 files changed, 927 insertions(+), 675 deletions(-) -- 2.9.5
[PATCH v3 06/20] mtd: spi-nor: Add a default_init() fixup hook for gd25q256
From: Boris Brezillon gd25q256 needs to tweak the ->quad_enable() implementation and the ->default_init() fixup hook is the perfect place to do that. This way, if we ever need to tweak more things for this flash, we won't have to add new fields in flash_info. We can get rid of the flash_info->quad_enable field as gd25q256 was the only user. Signed-off-by: Boris Brezillon [tudor.amba...@microchip.com: use ->default_init() hook instead of ->post_sfdp()] Signed-off-by: Tudor Ambarus --- v3: no changes drivers/mtd/spi-nor/spi-nor.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 8fd60e1eebd2..3dbbfe34d1d2 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -222,8 +222,6 @@ struct flash_info { /* Part specific fixup hooks. */ const struct spi_nor_fixups *fixups; - - int (*quad_enable)(struct spi_nor *nor); }; #define JEDEC_MFR(info)((info)->id[0]) @@ -2126,6 +2124,21 @@ static struct spi_nor_fixups mx25l25635_fixups = { .post_bfpt = mx25l25635_post_bfpt_fixups, }; +static void gd25q256_default_init(struct spi_nor *nor) +{ + /* +* Some manufacturer like GigaDevice may use different +* bit to set QE on different memories, so the MFR can't +* indicate the quad_enable method for this case, we need +* to set it in the default_init fixup hook. +*/ + nor->params.quad_enable = macronix_quad_enable; +} + +static struct spi_nor_fixups gd25q256_fixups = { + .default_init = gd25q256_default_init, +}; + /* NOTE: double check command sets and memory organization when you add * more nor chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. @@ -2218,7 +2231,7 @@ static const struct flash_info spi_nor_ids[] = { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - .quad_enable = macronix_quad_enable, + .fixups = _fixups, }, /* Intel/Numonyx -- xxxs33b */ @@ -4237,15 +4250,6 @@ static int spi_nor_init_params(struct spi_nor *nor) params->quad_enable = spansion_quad_enable; break; } - - /* -* Some manufacturer like GigaDevice may use different -* bit to set QE on different memories, so the MFR can't -* indicate the quad_enable method for this case, we need -* set it in flash info list. -*/ - if (info->quad_enable) - params->quad_enable = info->quad_enable; } spi_nor_manufacturer_init_params(nor); -- 2.9.5
[PATCH -next] ASoC: SOF: imx8: Fix return value check in imx8_probe()
In case of error, the function devm_ioremap_wc() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test. Fixes: 202acc565a1f ("ASoC: SOF: imx: Add i.MX8 HW support") Signed-off-by: Wei Yongjun --- sound/soc/sof/imx/imx8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index e502f584207f..263d4df35fe8 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -296,10 +296,10 @@ static int imx8_probe(struct snd_sof_dev *sdev) sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start, res.end - res.start + 1); - if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM])) { + if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n", base, size); - ret = PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]); + ret = -ENOMEM; goto exit_pdev_unregister; } sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
Re: [PATCH] x86/Hyper-V: Fix build error with CONFIG_HYPERV_TSCPAGE=N
On Mon, 26 Aug 2019, Vitaly Kuznetsov wrote: > Sasha Levin writes: > > > On Thu, Aug 22, 2019 at 10:39:46AM +0200, Vitaly Kuznetsov wrote: > >>lantianyu1...@gmail.com writes: > >> > >>> From: Tianyu Lan > >>> > >>> Both Hyper-V tsc page and Hyper-V tsc MSR code use variable > >>> hv_sched_clock_offset for their sched clock callback and so > >>> define the variable regardless of CONFIG_HYPERV_TSCPAGE setting. > >> > >>CONFIG_HYPERV_TSCPAGE is gone after my "x86/hyper-v: enable TSC page > >>clocksource on 32bit" patch. Do we still have an issue to fix? > > > > Yes. Let's get it fixed on older kernels (as such we need to tag this > > one for stable). The 32bit TSC patch won't come in before 5.4 anyway. > > > > Vitaly, does can you ack this patch? It might require you to re-spin > > your patch. > > > > Sure, no problem, > > Acked-by: Vitaly Kuznetsov > > I, however, was under the impression the patch fixes the issue with the > newly introduced sched clock: > > commit b74e1d61dbc614ff35ef3ad9267c61ed06b09051 > Author: Tianyu Lan > Date: Wed Aug 14 20:32:16 2019 +0800 > > clocksource/hyperv: Add Hyper-V specific sched clock function > > (and Fixes: tag is missing) > > and this is not in mainline as of v5.3-rc6. In tip/timers/core Thomas > already picked my "clocksource/drivers/hyperv: Enable TSC page > clocksource on 32bit" which also resolves the issue. No. I folded Sashas fix into the original clocksource patch and then added yours on top. Thanks, tglx
Re: [RFC 5/9] dt-bindings: arm: samsung: Convert Exynos PMU bindings to json-schema
On Fri, Aug 23, 2019 at 9:54 AM Krzysztof Kozlowski wrote: > > Convert Samsung Exynos Power Management Unit (PMU) bindings to DT schema > format using json-schema. > > Signed-off-by: Krzysztof Kozlowski > --- > .../devicetree/bindings/arm/samsung/pmu.txt | 72 -- > .../devicetree/bindings/arm/samsung/pmu.yaml | 93 +++ > 2 files changed, 93 insertions(+), 72 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/arm/samsung/pmu.txt > create mode 100644 Documentation/devicetree/bindings/arm/samsung/pmu.yaml > diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.yaml > b/Documentation/devicetree/bindings/arm/samsung/pmu.yaml > new file mode 100644 > index ..818c6f3488ef > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.yaml > @@ -0,0 +1,93 @@ > +# SPDX-License-Identifier: GPL-2.0 > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/arm/samsung/pmu.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Samsung Exynos SoC series Power Management Unit (PMU) > + > +maintainers: > + - Krzysztof Kozlowski > + > +properties: > + compatible: > +items: > + - enum: > + - samsung,exynos3250-pmu > + - samsung,exynos4210-pmu > + - samsung,exynos4412-pmu > + - samsung,exynos5250-pmu > + - samsung,exynos5260-pmu > + - samsung,exynos5410-pmu > + - samsung,exynos5420-pmu > + - samsung,exynos5433-pmu > + - samsung,exynos7-pmu > + - const: syscon > + > + reg: > +maxItems: 1 > + > + '#clock-cells': > +const: 1 > + > + clock-names: > +description: > + list of clock names for particular CLKOUT mux inputs > +# TODO: what is the maximum number of elements (mux inputs)? > +minItems: 1 > +maxItems: 32 > +items: > + - enum: This isn't correct as you are only defining possible names for the first item. Drop the '-' (making items a schema instead of a list) and then it applies to all. However, doing that will cause a meta-schema error which I need to fix to allow. Or if there's a small set of possibilities of number of inputs, you can list them under a 'oneOf' list. > + - clkout0 > + - clkout1 > + - clkout2 > + - clkout3 > + - clkout4 > + - clkout5 > + - clkout6 > + - clkout7 > + - clkout8 > + - clkout9 > + - clkout10 > + - clkout11 > + - clkout12 > + - clkout13 > + - clkout14 > + - clkout15 > + - clkout16 > + > + clocks: > +minItems: 1 > +maxItems: 32 > + > + interrupt-controller: > +description: > + Some PMUs are capable of behaving as an interrupt controller (mostly > + to wake up a suspended PMU). > + > + '#interrupt-cells': > +# TODO: must be identical to the that of the parent interrupt controller. There's not really a way to express that. Just state that in the description if you want. > +const: 3 > + > + # TODO: Mark interrupt-controller and #interrupt-cells as required, if one > is present No need, the core schemas handle that dependency. It would be good to define for which compatibles the properties are required. You can do this with if/then schema. There's several examples in the tree. > + # TODO: nodes defining the restart and poweroff syscon children > + > +required: > + - compatible > + - reg > + - '#clock-cells' > + - clock-names > + - clocks > + > +examples: > + - | > +pmu_system_controller: system-controller@1004 { > + compatible = "samsung,exynos5250-pmu", "syscon"; > + reg = <0x1004 0x5000>; > + interrupt-controller; > + #interrupt-cells = <3>; > + interrupt-parent = <>; > + #clock-cells = <1>; > + clock-names = "clkout16"; > + clocks = < 0>; // CLK_FIN_PLL > +}; > -- > 2.17.1 >
[PATCH] sched/fair: update_curr changed sum_exec_runtime to 1 when sum_exec_runtime is 0 beacuse some kernel code use sum_exec_runtime==0 to test task just be forked.
From: Chong Qiao Such as: cpu_cgroup_attach> sched_move_task> task_change_group_fair> task_move_group_fair> detach_task_cfs_rq> vruntime_normalized> /* * When !on_rq, vruntime of the task has usually NOT been normalized. * But there are some cases where it has already been normalized: * * - A forked child which is waiting for being woken up by * wake_up_new_task(). * - A task which has been woken up by try_to_wake_up() and * waiting for actually being woken up by sched_ttwu_pending(). */ if (!se->sum_exec_runtime || (p->state == TASK_WAKING && p->sched_remote_wakeup)) return true; p->se.sum_exec_runtime is 0, does not mean task not been run (A forked child which is waiting for being woken up by wake_up_new_task()). Task may have been scheduled multimes, but p->se.sum_exec_runtime is still 0, because delta_exec maybe 0 in update_curr. static void update_curr(struct cfs_rq *cfs_rq) { ... delta_exec = now - curr->exec_start; if (unlikely((s64)delta_exec <= 0)) return; ... curr->sum_exec_runtime += delta_exec; ... } Task has been run and is stopped(on_rq == 0), vruntime not been normalized, but se->sum_exec_runtime == 0. This cause vruntime_normalized set on_rq 1, and does not normalize vruntime. This may cause task use old vruntime in old cgroup, which maybe very large than task's vruntime in new cgroup. Which may cause task may not scheduled in run queue for long time after been waked up. Now I change sum_exec_runtime to 1 when sum_exec_runtime == 0 in update_curr to make sun_exec_runtime not 0. Signed-off-by: Chong Qiao --- kernel/sched/fair.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index bc9cfeaac8bd2..c4cd6249d9d2c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -841,8 +841,15 @@ static void update_curr(struct cfs_rq *cfs_rq) return; delta_exec = now - curr->exec_start; - if (unlikely((s64)delta_exec <= 0)) + if (unlikely((s64)delta_exec <= 0)) { + /* +* se.sum_exec_runtime == 0 means task is forked and wait to be run. +* So here change se.sum_exec_runtime to 1, to make it not 0. +*/ + if (!curr->sum_exec_runtime) + curr->sum_exec_runtime++; return; + } curr->exec_start = now; -- 2.17.1
Re: [PATCH 02/19] dax: Pass dax_dev to dax_writeback_mapping_range()
On Wed, Aug 21, 2019 at 01:57:03PM -0400, Vivek Goyal wrote: > Right now dax_writeback_mapping_range() is passed a bdev and dax_dev > is searched from that bdev name. > > virtio-fs does not have a bdev. So pass in dax_dev also to > dax_writeback_mapping_range(). If dax_dev is passed in, bdev is not > used otherwise dax_dev is searched using bdev. Please just pass in only the dax_device and get rid of the block device. The callers should have one at hand easily, e.g. for XFS just call xfs_find_daxdev_for_inode instead of xfs_find_bdev_for_inode.
Re: [PATCH 01/19] dax: remove block device dependencies
On Wed, Aug 21, 2019 at 01:57:02PM -0400, Vivek Goyal wrote: > From: Stefan Hajnoczi > > Although struct dax_device itself is not tied to a block device, some > DAX code assumes there is a block device. Make block devices optional > by allowing bdev to be NULL in commonly used DAX APIs. > > When there is no block device: > * Skip the partition offset calculation in bdev_dax_pgoff() > * Skip the blkdev_issue_zeroout() optimization > > Note that more block device assumptions remain but I haven't reach those > code paths yet. I think this should be split into two patches. For bdev_dax_pgoff I'd much rather have the partition offset if there is on in the daxdev somehow so that we can get rid of the block device entirely. Similarly for dax_range_is_aligned I'd rather have a pure dax way to offload zeroing rather than this bdev hack. In the long run I'd really like to make the bdev vs daxdev in iomap a union instead of having to carry both around.
linux-next: build warning after merge of the devfreq tree
Hi all, After merging the devfreq tree, today's linux-next build (x86_64 allmodconfig) produced this warning: drivers/devfreq/governor_passive.c: In function 'devfreq_passive_event_handler': drivers/devfreq/governor_passive.c:152:17: warning: unused variable 'dev' [-Wunused-variable] struct device *dev = devfreq->dev.parent; ^~~ Introduced by commit 0ef7c7cce43f ("PM / devfreq: passive: Use non-devm notifiers") -- Cheers, Stephen Rothwell pgpEgM_sN6G4u.pgp Description: OpenPGP digital signature
Re: [PATCH] powerpc/time: use feature fixup in __USE_RTC() instead of cpu feature.
Le 26/08/2019 à 13:41, Michael Ellerman a écrit : Christophe Leroy writes: sched_clock(), used by printk(), calls __USE_RTC() to know whether to use realtime clock or timebase. __USE_RTC() uses cpu_has_feature() which is initialised by machine_init(). Before machine_init(), __USE_RTC() returns true, leading to a program check exception on CPUs not having realtime clock. In order to be able to use printk() earlier, use feature fixup. Feature fixups are applies in early_init(), enabling the use of printk() earlier. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/time.h | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) The other option would be just to make this a compile time decision, eg. add CONFIG_PPC_601 and use that to gate whether we use RTC. Euh ... yes OK, why not. And that would help simplify many places in the code. I can propose something in that direction, but it will be a bigger change. Given how many 601 users there are, maybe 1?, I think that would be a simpler option and avoids complicating the code / binary for everyone else. However this patch doesn't complicate things more than it was with cpu_has_feature() which does exactly the same but using static keys, does it ? Christophe cheers diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 54f4ec1f9fab..3455cb54c333 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -42,7 +42,14 @@ struct div_result { /* Accessor functions for the timebase (RTC on 601) registers. */ /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ #ifdef CONFIG_PPC_BOOK3S_32 -#define __USE_RTC()(cpu_has_feature(CPU_FTR_USE_RTC)) +static inline bool __USE_RTC(void) +{ + asm_volatile_goto(ASM_FTR_IFCLR("nop;", "b %1;", %0) :: + "i" (CPU_FTR_USE_RTC) :: l_use_rtc); + return false; +l_use_rtc: + return true; +} #else #define __USE_RTC() 0 #endif -- 2.13.3
Re: [RFC] mm: Proactive compaction
On Thu, Aug 22, 2019 at 09:57:22PM +, Nitin Gupta wrote: > > Note that proactive compaction may reduce allocation latency but it is not > > free either. Even though the scanning and migration may happen in a kernel > > thread, tasks can incur faults while waiting for compaction to complete if > > the > > task accesses data being migrated. This means that costs are incurred by > > applications on a system that may never care about high-order allocation > > latency -- particularly if the allocations typically happen at application > > initialisation time. I recognise that kcompactd makes a bit of effort to > > compact memory out-of-band but it also is typically triggered in response to > > reclaim that was triggered by a high-order allocation request. i.e. the work > > done by the thread is triggered by an allocation request that hit the slow > > paths and not a preemptive measure. > > > > Hitting the slow path for every higher-order allocation is a signification > performance/latency issue for applications that requires a large number of > these allocations to succeed in bursts. To get some concrete numbers, I > made a small driver that allocates as many hugepages as possible and > measures allocation latency: > Every higher-order allocation does not necessarily hit the slow path nor does it incur equal latency. > The driver first tries to allocate hugepage using GFP_TRANSHUGE_LIGHT > (referred to as "Light" in the table below) and if that fails, tries to > allocate with `GFP_TRANSHUGE | __GFP_RETRY_MAYFAIL` (referred to as > "Fallback" in table below). We stop the allocation loop if both methods > fail. > > Table-1: hugepage allocation latencies on vanilla 5.3.0-rc5. All latencies > are in microsec. > > | GFP/Stat |Any | Light | Fallback | > |: | -: | --: | -: | > |count | 9908 | 788 | 9120 | > | min |0.0 | 0.0 | 1726.0 | > | max | 135387.0 | 142.0 | 135387.0 | > | mean |5494.66 |1.83 |5969.26 | > | stddev | 21624.04 |7.58 | 22476.06 | > Given that it is expected that there would be significant tail latencies, it would be better to analyse this in terms of percentiles. A very small number of high latency allocations would skew the mean significantly which is hinted by the stddev. > As you can see, the mean and stddev of allocation is extremely high with > the current approach of on-demand compaction. > > The system was fragmented from a userspace program as I described in this > patch description. The workload is mainly anonymous userspace pages which > as easy to move around. I intentionally avoided unmovable pages in this > test to see how much latency do we incur just by hitting the slow path for > a majority of allocations. > Even though, the penalty for proactive compaction is that applications that may have no interest in higher-order pages may still stall while their data is migrated if the data is hot. This is why I think the focus should be on reducing the latency of compaction -- it benefits applications that require higher-order latencies without increasing the overhead for unrelated applications. > > > > For a more proactive compaction, the approach taken here is to define > > > per page-order external fragmentation thresholds and let kcompactd > > > threads act on these thresholds. > > > > > > The low and high thresholds are defined per page-order and exposed > > > through sysfs: > > > > > > /sys/kernel/mm/compaction/order-[1..MAX_ORDER]/extfrag_{low,high} > > > > > > > These will be difficult for an admin to tune that is not extremely familiar > > with > > how external fragmentation is defined. If an admin asked "how much will > > stalls be reduced by setting this to a different value?", the answer will > > always > > be "I don't know, maybe some, maybe not". > > > > Yes, this is my main worry. These values can be set to emperically > determined values on highly specialized systems like database appliances. > However, on a generic system, there is no real reasonable value. > Yep, which means the tunable will be vulnerable to cargo-cult tuning recommendations. Or worse, the tuning recommendation will be a flat "disable THP". > Still, at the very least, I would like an interface that allows compacting > system to a reasonable state. Something like: > > compact_extfrag(node, zone, order, high, low) > > which start compaction if extfrag > high, and goes on till extfrag < low. > > It's possible that there are too many unmovable pages mixed around for > compaction to succeed, still it's a reasonable interface to expose rather > than forced on-demand style of compaction (please see data below). > > How (and if) to expose it to userspace (sysfs etc.) can be a separate > discussion. > That would be functionally similar to vm.compact_memory although it would either need an extension or a separate tunable. With sysfs, there could be a per-node
[tip: x86/cpu] x86/cpu/intel: Aggregate microserver naming
The following commit has been merged into the x86/cpu branch of tip: Commit-ID: d5e4ef22e053072ce03951a5beed0ce5244bee81 Gitweb: https://git.kernel.org/tip/d5e4ef22e053072ce03951a5beed0ce5244bee81 Author:Peter Zijlstra AuthorDate:Thu, 22 Aug 2019 12:23:10 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 11:49:04 +02:00 x86/cpu/intel: Aggregate microserver naming Currently big microservers have _XEON_D while small microservers have _X, Make it uniformly: _D. for i in `git grep -l "INTEL_FAM6_.*_\(X\|XEON_D\)"` do sed -i -e 's/\(INTEL_FAM6_ATOM_.*\)_X/\1_D/g' \ -e 's/\(INTEL_FAM6_.*\)_XEON_D/\1_D/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tony Luck Link: http://lkml.kernel.org/r/20190822102411.337145...@infradead.org Signed-off-by: Ingo Molnar --- arch/x86/events/intel/core.c | 20 ++-- arch/x86/events/intel/cstate.c| 12 ++-- arch/x86/events/intel/pt.c| 2 +- arch/x86/events/intel/rapl.c | 4 ++-- arch/x86/events/intel/uncore.c| 4 ++-- arch/x86/events/msr.c | 6 +++--- arch/x86/include/asm/intel-family.h | 10 +- arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/cpu/common.c | 4 ++-- arch/x86/kernel/cpu/intel.c | 4 ++-- arch/x86/kernel/cpu/mce/intel.c | 2 +- arch/x86/kernel/tsc.c | 2 +- drivers/cpufreq/intel_pstate.c| 6 +++--- drivers/edac/i10nm_base.c | 4 ++-- drivers/edac/pnd2_edac.c | 2 +- drivers/edac/sb_edac.c| 2 +- tools/power/x86/turbostat/turbostat.c | 22 +++--- 17 files changed, 54 insertions(+), 54 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 472b45c..dce329c 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3971,10 +3971,10 @@ static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x000a), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x0023), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_G, 1, 0x0014), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x0010), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x0709), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 4, 0x0f09), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 5, 0x0e02), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 2, 0x0010), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 3, 0x0709), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 4, 0x0f09), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 5, 0x0e02), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 2, 0x0b14), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x0021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x), @@ -4146,7 +4146,7 @@ static const struct x86_cpu_desc counter_freezing_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 2, 0x000e), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 9, 0x002e), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT,10, 0x0008), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_X, 1, 0x0028), + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_D, 1, 0x0028), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS,1, 0x0028), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS,8, 0x0006), {} @@ -4643,7 +4643,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_ATOM_SILVERMONT: - case INTEL_FAM6_ATOM_SILVERMONT_X: + case INTEL_FAM6_ATOM_SILVERMONT_D: case INTEL_FAM6_ATOM_SILVERMONT_MID: case INTEL_FAM6_ATOM_AIRMONT: case INTEL_FAM6_ATOM_AIRMONT_MID: @@ -4665,7 +4665,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_ATOM_GOLDMONT: - case INTEL_FAM6_ATOM_GOLDMONT_X: + case INTEL_FAM6_ATOM_GOLDMONT_D: x86_add_quirk(intel_counter_freezing_quirk); memcpy(hw_cache_event_ids, glm_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -4721,7 +4721,7 @@ __init int intel_pmu_init(void) name = "goldmont_plus"; break; - case INTEL_FAM6_ATOM_TREMONT_X: + case INTEL_FAM6_ATOM_TREMONT_D: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -4891,7 +4891,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_BROADWELL: - case INTEL_FAM6_BROADWELL_XEON_D: + case
[tip: x86/cpu] x86/cpu/intel: Aggregate big core mobile naming
The following commit has been merged into the x86/cpu branch of tip: Commit-ID: 2c1ce2da5925a725fa6a4b9561304fb61ed1f31f Gitweb: https://git.kernel.org/tip/2c1ce2da5925a725fa6a4b9561304fb61ed1f31f Author:Peter Zijlstra AuthorDate:Thu, 22 Aug 2019 12:23:08 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 11:21:11 +02:00 x86/cpu/intel: Aggregate big core mobile naming Currently big core mobile chips have either: - _L - _ULT - _MOBILE Make it uniformly: _L. for i in `git grep -l "INTEL_FAM6_.*_\(MOBILE\|ULT\)"` do sed -i -e 's/\(INTEL_FAM6_.*\)_\(MOBILE\|ULT\)/\1_L/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tony Luck Link: http://lkml.kernel.org/r/20190822102411.225140...@infradead.org Signed-off-by: Ingo Molnar --- arch/x86/events/intel/core.c | 20 ++--- arch/x86/events/intel/cstate.c| 18 ++-- arch/x86/events/intel/rapl.c | 10 +++ arch/x86/events/intel/uncore.c| 8 ++--- arch/x86/events/msr.c | 8 ++--- arch/x86/include/asm/intel-family.h | 10 +++ arch/x86/kernel/apic/apic.c | 6 ++-- arch/x86/kernel/cpu/bugs.c| 6 ++-- arch/x86/kernel/cpu/intel.c | 6 ++-- drivers/acpi/x86/utils.c | 4 +-- drivers/cpufreq/intel_pstate.c| 4 +-- tools/power/x86/turbostat/turbostat.c | 40 +- 12 files changed, 70 insertions(+), 70 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 76bff3a..22ef9cc 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3965,7 +3965,7 @@ static __init void intel_clovertown_quirk(void) static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x001f), - INTEL_CPU_DESC(INTEL_FAM6_HASWELL_ULT, 1, 0x001e), + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_L, 1, 0x001e), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x0015), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x0037), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x000a), @@ -3978,13 +3978,13 @@ static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 2, 0x0b14), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x0021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x), - INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_MOBILE,3, 0x007c), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x007c), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x007c), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 9, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 10, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 11, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 12, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L,9, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 10, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 11, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 12, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 10, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 11, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 12, 0x004e), @@ -4859,7 +4859,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: - case INTEL_FAM6_HASWELL_ULT: + case INTEL_FAM6_HASWELL_L: case INTEL_FAM6_HASWELL_GT3E: x86_add_quirk(intel_ht_bug); x86_add_quirk(intel_pebs_isolation_quirk); @@ -4955,9 +4955,9 @@ __init int intel_pmu_init(void) case INTEL_FAM6_SKYLAKE_X: pmem = true; /* fall through */ - case INTEL_FAM6_SKYLAKE_MOBILE: + case INTEL_FAM6_SKYLAKE_L: case INTEL_FAM6_SKYLAKE: - case INTEL_FAM6_KABYLAKE_MOBILE: + case INTEL_FAM6_KABYLAKE_L: case INTEL_FAM6_KABYLAKE: x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; @@ -5005,7 +5005,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_ICELAKE_XEON_D: pmem = true; /* fall through */ - case INTEL_FAM6_ICELAKE_MOBILE: + case INTEL_FAM6_ICELAKE_L: case INTEL_FAM6_ICELAKE: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/arch/x86/events/intel/cstate.c
[tip: perf/core] perf/x86/intel/pt: Clean up ToPA allocation path
The following commit has been merged into the perf/core branch of tip: Commit-ID: 90583af61d0c0d2826f42a297a03645b35c49085 Gitweb: https://git.kernel.org/tip/90583af61d0c0d2826f42a297a03645b35c49085 Author:Alexander Shishkin AuthorDate:Wed, 21 Aug 2019 15:47:22 +03:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:00:12 +02:00 perf/x86/intel/pt: Clean up ToPA allocation path Some of the allocation parameters are passed as function arguments, while the CPU number for per-cpu allocation is passed via the buffer object. There's no reason for this. Pass the CPU as a function argument instead. Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/20190821124727.73310-2-alexander.shish...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 15 +++ arch/x86/events/intel/pt.h | 2 -- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index d3dc227..9d9258f 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -670,7 +670,7 @@ static bool topa_table_full(struct topa *topa) * * Return: 0 on success or error code. */ -static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp) +static int topa_insert_pages(struct pt_buffer *buf, int cpu, gfp_t gfp) { struct topa *topa = buf->last; int order = 0; @@ -681,7 +681,7 @@ static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp) order = page_private(p); if (topa_table_full(topa)) { - topa = topa_alloc(buf->cpu, gfp); + topa = topa_alloc(cpu, gfp); if (!topa) return -ENOMEM; @@ -1061,20 +1061,20 @@ static void pt_buffer_fini_topa(struct pt_buffer *buf) * @size: Total size of all regions within this ToPA. * @gfp: Allocation flags. */ -static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages, - gfp_t gfp) +static int pt_buffer_init_topa(struct pt_buffer *buf, int cpu, + unsigned long nr_pages, gfp_t gfp) { struct topa *topa; int err; - topa = topa_alloc(buf->cpu, gfp); + topa = topa_alloc(cpu, gfp); if (!topa) return -ENOMEM; topa_insert_table(buf, topa); while (buf->nr_pages < nr_pages) { - err = topa_insert_pages(buf, gfp); + err = topa_insert_pages(buf, cpu, gfp); if (err) { pt_buffer_fini_topa(buf); return -ENOMEM; @@ -1124,13 +1124,12 @@ pt_buffer_setup_aux(struct perf_event *event, void **pages, if (!buf) return NULL; - buf->cpu = cpu; buf->snapshot = snapshot; buf->data_pages = pages; INIT_LIST_HEAD(>tables); - ret = pt_buffer_init_topa(buf, nr_pages, GFP_KERNEL); + ret = pt_buffer_init_topa(buf, cpu, nr_pages, GFP_KERNEL); if (ret) { kfree(buf); return NULL; diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h index 63fe406..8de8ed0 100644 --- a/arch/x86/events/intel/pt.h +++ b/arch/x86/events/intel/pt.h @@ -53,7 +53,6 @@ struct pt_pmu { /** * struct pt_buffer - buffer configuration; one buffer per task_struct or * cpu, depending on perf event configuration - * @cpu: cpu for per-cpu allocation * @tables:list of ToPA tables in this buffer * @first: shorthand for first topa table * @last: shorthand for last topa table @@ -71,7 +70,6 @@ struct pt_pmu { * @topa_index:table of topa entries indexed by page offset */ struct pt_buffer { - int cpu; struct list_headtables; struct topa *first, *last, *cur; unsigned intcur_idx;
[tip: x86/cpu] x86/cpu/intel: Fix rename fallout
The following commit has been merged into the x86/cpu branch of tip: Commit-ID: 26ee9ccc117b9c4179f0a1c65c67f71a0a5a0afe Gitweb: https://git.kernel.org/tip/26ee9ccc117b9c4179f0a1c65c67f71a0a5a0afe Author:Ingo Molnar AuthorDate:Mon, 26 Aug 2019 12:19:06 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 13:06:29 +02:00 x86/cpu/intel: Fix rename fallout The scripts missed a macro construct of intel_idle.c and other files. Signed-off-by: Ingo Molnar Cc: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tony Luck Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/idle/intel_idle.c| 26 +++ drivers/platform/x86/intel_pmc_core.c| 12 +++ drivers/platform/x86/intel_pmc_core_pltdrv.c | 12 +++ drivers/powercap/intel_rapl_common.c | 32 +-- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index ac58487..347b08b 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1072,26 +1072,26 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { INTEL_CPU_FAM6(ATOM_AIRMONT,idle_cpu_cht), INTEL_CPU_FAM6(IVYBRIDGE, idle_cpu_ivb), INTEL_CPU_FAM6(IVYBRIDGE_X, idle_cpu_ivt), - INTEL_CPU_FAM6(HASWELL_CORE,idle_cpu_hsw), + INTEL_CPU_FAM6(HASWELL, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_X, idle_cpu_hsw), - INTEL_CPU_FAM6(HASWELL_ULT, idle_cpu_hsw), - INTEL_CPU_FAM6(HASWELL_GT3E,idle_cpu_hsw), - INTEL_CPU_FAM6(ATOM_SILVERMONT_X, idle_cpu_avn), - INTEL_CPU_FAM6(BROADWELL_CORE, idle_cpu_bdw), - INTEL_CPU_FAM6(BROADWELL_GT3E, idle_cpu_bdw), + INTEL_CPU_FAM6(HASWELL_L, idle_cpu_hsw), + INTEL_CPU_FAM6(HASWELL_G, idle_cpu_hsw), + INTEL_CPU_FAM6(ATOM_SILVERMONT_D, idle_cpu_avn), + INTEL_CPU_FAM6(BROADWELL, idle_cpu_bdw), + INTEL_CPU_FAM6(BROADWELL_G, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_X, idle_cpu_bdw), - INTEL_CPU_FAM6(BROADWELL_XEON_D,idle_cpu_bdw), - INTEL_CPU_FAM6(SKYLAKE_MOBILE, idle_cpu_skl), - INTEL_CPU_FAM6(SKYLAKE_DESKTOP, idle_cpu_skl), - INTEL_CPU_FAM6(KABYLAKE_MOBILE, idle_cpu_skl), - INTEL_CPU_FAM6(KABYLAKE_DESKTOP,idle_cpu_skl), + INTEL_CPU_FAM6(BROADWELL_D, idle_cpu_bdw), + INTEL_CPU_FAM6(SKYLAKE_L, idle_cpu_skl), + INTEL_CPU_FAM6(SKYLAKE, idle_cpu_skl), + INTEL_CPU_FAM6(KABYLAKE_L, idle_cpu_skl), + INTEL_CPU_FAM6(KABYLAKE,idle_cpu_skl), INTEL_CPU_FAM6(SKYLAKE_X, idle_cpu_skx), INTEL_CPU_FAM6(XEON_PHI_KNL,idle_cpu_knl), INTEL_CPU_FAM6(XEON_PHI_KNM,idle_cpu_knl), INTEL_CPU_FAM6(ATOM_GOLDMONT, idle_cpu_bxt), INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, idle_cpu_bxt), - INTEL_CPU_FAM6(ATOM_GOLDMONT_X, idle_cpu_dnv), - INTEL_CPU_FAM6(ATOM_TREMONT_X, idle_cpu_dnv), + INTEL_CPU_FAM6(ATOM_GOLDMONT_D, idle_cpu_dnv), + INTEL_CPU_FAM6(ATOM_TREMONT_D, idle_cpu_dnv), {} }; diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index c510d0d..fd1bfd5 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -806,12 +806,12 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) #endif /* CONFIG_DEBUG_FS */ static const struct x86_cpu_id intel_pmc_core_ids[] = { - INTEL_CPU_FAM6(SKYLAKE_MOBILE, spt_reg_map), - INTEL_CPU_FAM6(SKYLAKE_DESKTOP, spt_reg_map), - INTEL_CPU_FAM6(KABYLAKE_MOBILE, spt_reg_map), - INTEL_CPU_FAM6(KABYLAKE_DESKTOP, spt_reg_map), - INTEL_CPU_FAM6(CANNONLAKE_MOBILE, cnp_reg_map), - INTEL_CPU_FAM6(ICELAKE_MOBILE, icl_reg_map), + INTEL_CPU_FAM6(SKYLAKE_L, spt_reg_map), + INTEL_CPU_FAM6(SKYLAKE, spt_reg_map), + INTEL_CPU_FAM6(KABYLAKE_L, spt_reg_map), + INTEL_CPU_FAM6(KABYLAKE, spt_reg_map), + INTEL_CPU_FAM6(CANNONLAKE_L, cnp_reg_map), + INTEL_CPU_FAM6(ICELAKE_L, icl_reg_map), INTEL_CPU_FAM6(ICELAKE_NNPI, icl_reg_map), {} }; diff --git a/drivers/platform/x86/intel_pmc_core_pltdrv.c b/drivers/platform/x86/intel_pmc_core_pltdrv.c index a8754a6..5977e0d 100644 --- a/drivers/platform/x86/intel_pmc_core_pltdrv.c +++ b/drivers/platform/x86/intel_pmc_core_pltdrv.c @@ -30,12 +30,12 @@ static struct platform_device pmc_core_device = { * other list may grow, but this list should not. */ static const
[tip: perf/core] perf/x86/intel/pt: Use pointer arithmetics instead in ToPA entry calculation
The following commit has been merged into the perf/core branch of tip: Commit-ID: 539f7c26b41d4ed7d88dd9756de3966ae7ca07b4 Gitweb: https://git.kernel.org/tip/539f7c26b41d4ed7d88dd9756de3966ae7ca07b4 Author:Alexander Shishkin AuthorDate:Wed, 21 Aug 2019 15:47:24 +03:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:00:13 +02:00 perf/x86/intel/pt: Use pointer arithmetics instead in ToPA entry calculation Currently, pt_buffer_reset_offsets() calculates the current ToPA entry by casting pointers to addresses and performing ungainly subtractions and divisions instead of a simpler pointer arithmetic, which would be perfectly applicable in that case. Fix that. Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/20190821124727.73310-4-alexander.shish...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index f269875..188d45f 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -1030,8 +1030,7 @@ static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head) pg = pt_topa_next_entry(buf, pg); buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK); - buf->cur_idx = ((unsigned long)buf->topa_index[pg] - - (unsigned long)buf->cur) / sizeof(struct topa_entry); + buf->cur_idx = buf->topa_index[pg] - TOPA_ENTRY(buf->cur, 0); buf->output_off = head & (pt_buffer_region_size(buf) - 1); local64_set(>head, head);
[tip: perf/core] perf/x86/intel/pt: Get rid of reverse lookup table for ToPA
The following commit has been merged into the perf/core branch of tip: Commit-ID: 39152ee51b77851689f9b23fde6f610d13566c39 Gitweb: https://git.kernel.org/tip/39152ee51b77851689f9b23fde6f610d13566c39 Author:Alexander Shishkin AuthorDate:Wed, 21 Aug 2019 15:47:27 +03:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:00:16 +02:00 perf/x86/intel/pt: Get rid of reverse lookup table for ToPA In order to quickly find a ToPA entry by its page offset in the buffer, we're using a reverse lookup table. The problem with it is that it's a large array of mostly similar pointers, especially so now that we're using high order allocations from the page allocator. Because its size is limited to whatever is the maximum for kmalloc(), it places a limit on the number of ToPA entries per buffer, and therefore, on the total buffer size, which otherwise doesn't have to be there. Replace the reverse lookup table with a simple runtime lookup. With the high order AUX allocations in place, the runtime penalty of such a lookup is much smaller and in cases where all entries in a ToPA table are of the same size, the complexity is O(1). Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/20190821124727.73310-7-alexander.shish...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 194 +++- arch/x86/events/intel/pt.h | 10 +- 2 files changed, 131 insertions(+), 73 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 0f38ed3..fa43d90 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -551,12 +551,14 @@ static void pt_config_buffer(void *buf, unsigned int topa_idx, * @offset:offset of the first entry in this table in the buffer * @size: total size of all entries in this table * @last: index of the last initialized entry in this table + * @z_count: how many times the first entry repeats */ struct topa { struct list_headlist; u64 offset; size_t size; int last; + unsigned intz_count; }; /* @@ -598,6 +600,7 @@ static inline phys_addr_t topa_pfn(struct topa *topa) ? _to_page(t)->table[(t)->last]\ : _to_page(t)->table[(i)]) #define TOPA_ENTRY_SIZE(t, i) (sizes(TOPA_ENTRY((t), (i))->size)) +#define TOPA_ENTRY_PAGES(t, i) (1 << TOPA_ENTRY((t), (i))->size) /** * topa_alloc() - allocate page-sized ToPA table @@ -713,6 +716,11 @@ static int topa_insert_pages(struct pt_buffer *buf, int cpu, gfp_t gfp) topa_insert_table(buf, topa); } + if (topa->z_count == topa->last - 1) { + if (order == TOPA_ENTRY(topa, topa->last - 1)->size) + topa->z_count++; + } + TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT; TOPA_ENTRY(topa, -1)->size = order; if (!buf->snapshot && @@ -756,6 +764,8 @@ static void pt_topa_dump(struct pt_buffer *buf) tp->table[i].stop) || tp->table[i].end) break; + if (!i && topa->z_count) + i += topa->z_count; } } } @@ -907,29 +917,97 @@ static void pt_read_offset(struct pt_buffer *buf) buf->cur_idx = (offset & 0xff80) >> 7; } -/** - * pt_topa_next_entry() - obtain index of the first page in the next ToPA entry - * @buf: PT buffer. - * @pg:Page offset in the buffer. - * - * When advancing to the next output region (ToPA entry), given a page offset - * into the buffer, we need to find the offset of the first page in the next - * region. - */ -static unsigned int pt_topa_next_entry(struct pt_buffer *buf, unsigned int pg) +static struct topa_entry * +pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg) +{ + struct topa_page *tp; + struct topa *topa; + unsigned int idx, cur_pg = 0, z_pg = 0, start_idx = 0; + + /* +* Indicates a bug in the caller. +*/ + if (WARN_ON_ONCE(pg >= buf->nr_pages)) + return NULL; + + /* +* First, find the ToPA table where @pg fits. With high +* order allocations, there shouldn't be many of these. +*/ + list_for_each_entry(topa, >tables, list) { + if (topa->offset + topa->size > pg << PAGE_SHIFT) + goto found; + } + + /* +* Hitting this means we have a problem in the ToPA +* allocation code. +*/ + WARN_ON_ONCE(1); + + return NULL; + +found: + /* +* Indicates a problem in the ToPA allocation
[tip: x86/cpu] x86/cpu/intel: Add common OPTDIFFs
The following commit has been merged into the x86/cpu branch of tip: Commit-ID: b95a1e89f1007dd552d9756c077bedc74183d8ac Gitweb: https://git.kernel.org/tip/b95a1e89f1007dd552d9756c077bedc74183d8ac Author:Peter Zijlstra AuthorDate:Thu, 22 Aug 2019 12:23:11 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 11:49:04 +02:00 x86/cpu/intel: Add common OPTDIFFs Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tony Luck Link: http://lkml.kernel.org/r/20190822102411.393701...@infradead.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/intel-family.h | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 76dc9ab..5c05b2d 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -5,9 +5,6 @@ /* * "Big Core" Processors (Branded as Core, Xeon, etc...) * - * The "_X" parts are generally the EP and EX Xeons, or the - * "Extreme" ones, like Broadwell-E, or Atom microserver. - * * While adding a new CPUID for a new microarchitecture, add a new * group to keep logically sorted out in chronological order. Within * that group keep the CPUID for the variants sorted by model number. @@ -21,9 +18,19 @@ * MICROARCH Is the code name for the micro-architecture for this core. * N.B. Not the platform name. * OPTDIFF If needed, a short string to differentiate by market segment. - * Exact strings here will vary over time. _DESKTOP, _MOBILE, and - * _X (short for Xeon server) should be used when they are - * appropriate. + * + * Common OPTDIFFs: + * + * - regular client parts + * _L - regular mobile parts + * _G - parts with extra graphics on + * _X - regular server parts + * _D - micro server parts + * + * Historical OPTDIFFs: + * + * _EP - 2 socket server parts + * _EX - 4+ socket server parts * * The #define line may optionally include a comment including platform names. */ @@ -91,6 +98,8 @@ #define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */ #define INTEL_FAM6_ATOM_GOLDMONT_D 0x5F /* Denverton */ + +/* Note: the micro-architecture is "Goldmont Plus" */ #define INTEL_FAM6_ATOM_GOLDMONT_PLUS 0x7A /* Gemini Lake */ #define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */
[tip: x86/cpu] x86/cpu/intel: Aggregate big core client naming
The following commit has been merged into the x86/cpu branch of tip: Commit-ID: 33b154d766de704c11a098f3528debbcfb74326f Gitweb: https://git.kernel.org/tip/33b154d766de704c11a098f3528debbcfb74326f Author:Peter Zijlstra AuthorDate:Thu, 22 Aug 2019 12:23:07 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 11:21:11 +02:00 x86/cpu/intel: Aggregate big core client naming Currently the big core client models either have: - no OPTDIFF - _CORE - _DESKTOP Make it uniformly: 'no OPTDIFF'. for i in `git grep -l "INTEL_FAM6_.*_\(CORE\|DESKTOP\)"` do sed -i -e 's/\(INTEL_FAM6_.*\)_\(CORE\|DESKTOP\)/\1/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tony Luck Link: http://lkml.kernel.org/r/20190822102411.168563...@infradead.org Signed-off-by: Ingo Molnar --- arch/x86/events/intel/core.c | 26 arch/x86/events/intel/cstate.c| 22 ++-- arch/x86/events/intel/pt.c| 2 +- arch/x86/events/intel/rapl.c | 10 - arch/x86/events/intel/uncore.c| 12 +-- arch/x86/events/msr.c | 8 +++ arch/x86/include/asm/intel-family.h | 10 - arch/x86/kernel/apic/apic.c | 8 +++ arch/x86/kernel/cpu/bugs.c| 8 +++ arch/x86/kernel/cpu/intel.c | 10 - drivers/cpufreq/intel_pstate.c| 12 +-- drivers/idle/intel_idle.c | 2 +- tools/power/x86/turbostat/turbostat.c | 28 +- 13 files changed, 79 insertions(+), 79 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 648260b..76bff3a 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3964,12 +3964,12 @@ static __init void intel_clovertown_quirk(void) } static const struct x86_cpu_desc isolation_ucodes[] = { - INTEL_CPU_DESC(INTEL_FAM6_HASWELL_CORE, 3, 0x001f), + INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x001f), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_ULT, 1, 0x001e), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x0015), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x0037), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x000a), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_CORE,4, 0x0023), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x0023), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_GT3E,1, 0x0014), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x0010), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x0709), @@ -3979,16 +3979,16 @@ static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x0021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_MOBILE,3, 0x007c), - INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_DESKTOP, 3, 0x007c), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 9, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x007c), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 9, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 10, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 11, 0x004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 12, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 10, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 11, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 12, 0x004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 13, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 10, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 11, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 12, 0x004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 13, 0x004e), {} }; @@ -4857,7 +4857,7 @@ __init int intel_pmu_init(void) break; - case INTEL_FAM6_HASWELL_CORE: + case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_ULT: case INTEL_FAM6_HASWELL_GT3E: @@ -4890,7 +4890,7 @@ __init int intel_pmu_init(void) name = "haswell"; break; - case INTEL_FAM6_BROADWELL_CORE: + case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: case INTEL_FAM6_BROADWELL_GT3E: case INTEL_FAM6_BROADWELL_X: @@ -4956,9 +4956,9 @@ __init int intel_pmu_init(void) pmem = true; /* fall through */
[tip: x86/urgent] x86/apic: Fix arch_dynirq_lower_bound() bug for DT enabled machines
The following commit has been merged into the x86/urgent branch of tip: Commit-ID: 3e5bedc2c258341702ddffbd7688c5e6eb01eafa Gitweb: https://git.kernel.org/tip/3e5bedc2c258341702ddffbd7688c5e6eb01eafa Author:Thomas Gleixner AuthorDate:Wed, 21 Aug 2019 15:16:31 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:11:23 +02:00 x86/apic: Fix arch_dynirq_lower_bound() bug for DT enabled machines Rahul Tanwar reported the following bug on DT systems: > 'ioapic_dynirq_base' contains the virtual IRQ base number. Presently, it is > updated to the end of hardware IRQ numbers but this is done only when IOAPIC > configuration type is IOAPIC_DOMAIN_LEGACY or IOAPIC_DOMAIN_STRICT. There is > a third type IOAPIC_DOMAIN_DYNAMIC which applies when IOAPIC configuration > comes from devicetree. > > See dtb_add_ioapic() in arch/x86/kernel/devicetree.c > > In case of IOAPIC_DOMAIN_DYNAMIC (DT/OF based system), 'ioapic_dynirq_base' > remains to zero initialized value. This means that for OF based systems, > virtual IRQ base will get set to zero. Such systems will very likely not even boot. For DT enabled machines ioapic_dynirq_base is irrelevant and not updated, so simply map the IRQ base 1:1 instead. Reported-by: Rahul Tanwar Tested-by: Rahul Tanwar Tested-by: Andy Shevchenko Signed-off-by: Thomas Gleixner Cc: Alexander Shishkin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: a...@linux.intel.com Cc: b...@alien8.de Cc: cheol.yong@intel.com Cc: qi-ming...@intel.com Cc: rahul.tan...@intel.com Cc: r...@linux.ibm.com Cc: tony.l...@intel.com Link: http://lkml.kernel.org/r/20190821081330.1187-1-rahul.tan...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/io_apic.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index c7bb6c6..d6af97f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2438,7 +2438,13 @@ unsigned int arch_dynirq_lower_bound(unsigned int from) * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use * gsi_top if ioapic_dynirq_base hasn't been initialized yet. */ - return ioapic_initialized ? ioapic_dynirq_base : gsi_top; + if (!ioapic_initialized) + return gsi_top; + /* +* For DT enabled machines ioapic_dynirq_base is irrelevant and not +* updated. So simply return @from if ioapic_dynirq_base == 0. +*/ + return ioapic_dynirq_base ? : from; } #ifdef CONFIG_X86_32
[tip: x86/cpu] x86/cpu/intel: Aggregate big core graphics naming
The following commit has been merged into the x86/cpu branch of tip: Commit-ID: 7d54f81be6a3acea9e7289f25aba83a9ab5adc6e Gitweb: https://git.kernel.org/tip/7d54f81be6a3acea9e7289f25aba83a9ab5adc6e Author:Peter Zijlstra AuthorDate:Thu, 22 Aug 2019 12:23:09 +02:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 11:49:00 +02:00 x86/cpu/intel: Aggregate big core graphics naming Currently big core clients with extra graphics on have: - _G - _GT3E Make it uniformly: _G for i in `git grep -l "INTEL_FAM6_.*_GT3E"` do sed -i -e 's/\(INTEL_FAM6_.*\)_GT3E/\1_G/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tony Luck Link: http://lkml.kernel.org/r/20190822102411.281169...@infradead.org Signed-off-by: Ingo Molnar --- arch/x86/events/intel/core.c | 8 arch/x86/events/intel/cstate.c| 8 arch/x86/events/intel/pt.c| 2 +- arch/x86/events/intel/rapl.c | 4 ++-- arch/x86/events/intel/uncore.c| 4 ++-- arch/x86/events/msr.c | 4 ++-- arch/x86/include/asm/intel-family.h | 4 ++-- arch/x86/kernel/apic/apic.c | 4 ++-- arch/x86/kernel/cpu/bugs.c| 4 ++-- arch/x86/kernel/cpu/intel.c | 4 ++-- drivers/cpufreq/intel_pstate.c| 4 ++-- tools/power/x86/turbostat/turbostat.c | 18 +- 12 files changed, 34 insertions(+), 34 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 22ef9cc..472b45c 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3966,11 +3966,11 @@ static __init void intel_clovertown_quirk(void) static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x001f), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_L, 1, 0x001e), - INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x0015), + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_G, 1, 0x0015), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x0037), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x000a), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x0023), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_GT3E,1, 0x0014), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_G, 1, 0x0014), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x0010), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x0709), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 4, 0x0f09), @@ -4860,7 +4860,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_L: - case INTEL_FAM6_HASWELL_GT3E: + case INTEL_FAM6_HASWELL_G: x86_add_quirk(intel_ht_bug); x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; @@ -4892,7 +4892,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: - case INTEL_FAM6_BROADWELL_GT3E: + case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 9b014e8..03d7a40 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -593,9 +593,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_IVYBRIDGE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_IVYBRIDGE_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_X,snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_GT3E, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_X, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_G, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_L, hswult_cstates), @@ -605,7 +605,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL,snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_XEON_D, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_GT3E, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_G, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_L, snb_cstates), diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 8cb9626..d0195d1 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -206,7 +206,7 @@ static int
[tip: perf/core] perf/x86/intel/pt: Split ToPA metadata and page layout
The following commit has been merged into the perf/core branch of tip: Commit-ID: 38bb8d77d0b932a0773b5de2ef42479409314f96 Gitweb: https://git.kernel.org/tip/38bb8d77d0b932a0773b5de2ef42479409314f96 Author:Alexander Shishkin AuthorDate:Wed, 21 Aug 2019 15:47:25 +03:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:00:14 +02:00 perf/x86/intel/pt: Split ToPA metadata and page layout PT uses page sized ToPA tables, where the ToPA table resides at the bottom and its driver-specific metadata taking up a few words at the top of the page. The split is currently calculated manually and needs to be redone every time a field is added to or removed from the metadata structure. Also, the 32-bit version can be made smaller. By splitting the table and metadata into separate structures, we are making the compiler figure out the division of the page. Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/20190821124727.73310-5-alexander.shish...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 93 +++-- 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 188d45f..2e3f068 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -545,16 +545,8 @@ static void pt_config_buffer(void *buf, unsigned int topa_idx, wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg); } -/* - * Keep ToPA table-related metadata on the same page as the actual table, - * taking up a few words from the top - */ - -#define TENTS_PER_PAGE (((PAGE_SIZE - 40) / sizeof(struct topa_entry)) - 1) - /** - * struct topa - page-sized ToPA table with metadata at the top - * @table: actual ToPA table entries, as understood by PT hardware + * struct topa - ToPA metadata * @list: linkage to struct pt_buffer's list of tables * @phys: physical address of this page * @offset:offset of the first entry in this table in the buffer @@ -562,7 +554,6 @@ static void pt_config_buffer(void *buf, unsigned int topa_idx, * @last: index of the last initialized entry in this table */ struct topa { - struct topa_entry table[TENTS_PER_PAGE]; struct list_headlist; u64 phys; u64 offset; @@ -570,8 +561,39 @@ struct topa { int last; }; +/* + * Keep ToPA table-related metadata on the same page as the actual table, + * taking up a few words from the top + */ + +#define TENTS_PER_PAGE \ + ((PAGE_SIZE - sizeof(struct topa)) / sizeof(struct topa_entry)) + +/** + * struct topa_page - page-sized ToPA table with metadata at the top + * @table: actual ToPA table entries, as understood by PT hardware + * @topa: metadata + */ +struct topa_page { + struct topa_entry table[TENTS_PER_PAGE]; + struct topa topa; +}; + +static inline struct topa_page *topa_to_page(struct topa *topa) +{ + return container_of(topa, struct topa_page, topa); +} + +static inline struct topa_page *topa_entry_to_page(struct topa_entry *te) +{ + return (struct topa_page *)((unsigned long)te & PAGE_MASK); +} + /* make -1 stand for the last table entry */ -#define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)]) +#define TOPA_ENTRY(t, i) \ + ((i) == -1 \ + ? _to_page(t)->table[(t)->last]\ + : _to_page(t)->table[(i)]) #define TOPA_ENTRY_SIZE(t, i) (sizes(TOPA_ENTRY((t), (i))->size)) /** @@ -584,27 +606,27 @@ struct topa { static struct topa *topa_alloc(int cpu, gfp_t gfp) { int node = cpu_to_node(cpu); - struct topa *topa; + struct topa_page *tp; struct page *p; p = alloc_pages_node(node, gfp | __GFP_ZERO, 0); if (!p) return NULL; - topa = page_address(p); - topa->last = 0; - topa->phys = page_to_phys(p); + tp = page_address(p); + tp->topa.last = 0; + tp->topa.phys = page_to_phys(p); /* * In case of singe-entry ToPA, always put the self-referencing END * link as the 2nd entry in the table */ if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) { - TOPA_ENTRY(topa, 1)->base = topa->phys >> TOPA_SHIFT; - TOPA_ENTRY(topa, 1)->end = 1; + TOPA_ENTRY(>topa, 1)->base = tp->topa.phys; + TOPA_ENTRY(>topa, 1)->end = 1; } - return topa; + return >topa; } /** @@ -714,22 +736,23 @@ static void pt_topa_dump(struct pt_buffer *buf) struct topa *topa; list_for_each_entry(topa, >tables, list) {
[tip: perf/core] perf/x86/intel/pt: Use helpers to obtain ToPA entry size
The following commit has been merged into the perf/core branch of tip: Commit-ID: fffec50f541ace292383c0cbe9a2a97d16d201c6 Gitweb: https://git.kernel.org/tip/fffec50f541ace292383c0cbe9a2a97d16d201c6 Author:Alexander Shishkin AuthorDate:Wed, 21 Aug 2019 15:47:23 +03:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:00:13 +02:00 perf/x86/intel/pt: Use helpers to obtain ToPA entry size There are a few places in the PT driver that need to obtain the size of a ToPA entry, some of them for the current ToPA entry in the buffer. Use helpers for those, to make the lines shorter and more readable. Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/20190821124727.73310-3-alexander.shish...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 9d9258f..f269875 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -572,6 +572,7 @@ struct topa { /* make -1 stand for the last table entry */ #define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)]) +#define TOPA_ENTRY_SIZE(t, i) (sizes(TOPA_ENTRY((t), (i))->size)) /** * topa_alloc() - allocate page-sized ToPA table @@ -771,7 +772,7 @@ static void pt_update_head(struct pt *pt) /* offset of the current output region within this table */ for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++) - base += sizes(buf->cur->table[topa_idx].size); + base += TOPA_ENTRY_SIZE(buf->cur, topa_idx); if (buf->snapshot) { local_set(>data_size, base); @@ -800,7 +801,7 @@ static void *pt_buffer_region(struct pt_buffer *buf) */ static size_t pt_buffer_region_size(struct pt_buffer *buf) { - return sizes(buf->cur->table[buf->cur_idx].size); + return TOPA_ENTRY_SIZE(buf->cur, buf->cur_idx); } /** @@ -830,7 +831,7 @@ static void pt_handle_status(struct pt *pt) * know. */ if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) || - buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) { + buf->output_off == pt_buffer_region_size(buf)) { perf_aux_output_flag(>handle, PERF_AUX_FLAG_TRUNCATED); advance++; @@ -925,8 +926,7 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, unsigned long idx, npages, wakeup; /* can't stop in the middle of an output region */ - if (buf->output_off + handle->size + 1 < - sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) { + if (buf->output_off + handle->size + 1 < pt_buffer_region_size(buf)) { perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); return -EINVAL; } @@ -1032,7 +1032,7 @@ static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head) buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK); buf->cur_idx = ((unsigned long)buf->topa_index[pg] - (unsigned long)buf->cur) / sizeof(struct topa_entry); - buf->output_off = head & (sizes(buf->cur->table[buf->cur_idx].size) - 1); + buf->output_off = head & (pt_buffer_region_size(buf) - 1); local64_set(>head, head); local_set(>data_size, 0);
[tip: perf/core] perf/x86/intel/pt: Free up space in a ToPA descriptor
The following commit has been merged into the perf/core branch of tip: Commit-ID: 91feca5e2ecc9752894d57c9a72c2645471929c3 Gitweb: https://git.kernel.org/tip/91feca5e2ecc9752894d57c9a72c2645471929c3 Author:Alexander Shishkin AuthorDate:Wed, 21 Aug 2019 15:47:26 +03:00 Committer: Ingo Molnar CommitterDate: Mon, 26 Aug 2019 12:00:15 +02:00 perf/x86/intel/pt: Free up space in a ToPA descriptor Currently, we're storing physical address of a ToPA table in its descriptor, which is completely unnecessary. Since the descriptor and the table itself share the same page, reducing the descriptor size leaves more space for the table. Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/20190821124727.73310-6-alexander.shish...@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 2e3f068..0f38ed3 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -548,14 +548,12 @@ static void pt_config_buffer(void *buf, unsigned int topa_idx, /** * struct topa - ToPA metadata * @list: linkage to struct pt_buffer's list of tables - * @phys: physical address of this page * @offset:offset of the first entry in this table in the buffer * @size: total size of all entries in this table * @last: index of the last initialized entry in this table */ struct topa { struct list_headlist; - u64 phys; u64 offset; size_t size; int last; @@ -589,6 +587,11 @@ static inline struct topa_page *topa_entry_to_page(struct topa_entry *te) return (struct topa_page *)((unsigned long)te & PAGE_MASK); } +static inline phys_addr_t topa_pfn(struct topa *topa) +{ + return PFN_DOWN(virt_to_phys(topa_to_page(topa))); +} + /* make -1 stand for the last table entry */ #define TOPA_ENTRY(t, i) \ ((i) == -1 \ @@ -615,14 +618,13 @@ static struct topa *topa_alloc(int cpu, gfp_t gfp) tp = page_address(p); tp->topa.last = 0; - tp->topa.phys = page_to_phys(p); /* * In case of singe-entry ToPA, always put the self-referencing END * link as the 2nd entry in the table */ if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) { - TOPA_ENTRY(>topa, 1)->base = tp->topa.phys; + TOPA_ENTRY(>topa, 1)->base = page_to_phys(p); TOPA_ENTRY(>topa, 1)->end = 1; } @@ -666,7 +668,7 @@ static void topa_insert_table(struct pt_buffer *buf, struct topa *topa) BUG_ON(last->last != TENTS_PER_PAGE - 1); - TOPA_ENTRY(last, -1)->base = topa->phys >> TOPA_SHIFT; + TOPA_ENTRY(last, -1)->base = topa_pfn(topa); TOPA_ENTRY(last, -1)->end = 1; } @@ -739,8 +741,8 @@ static void pt_topa_dump(struct pt_buffer *buf) struct topa_page *tp = topa_to_page(topa); int i; - pr_debug("# table @%p (%016Lx), off %llx size %zx\n", tp->table, -topa->phys, topa->offset, topa->size); + pr_debug("# table @%p, off %llx size %zx\n", tp->table, +topa->offset, topa->size); for (i = 0; i < TENTS_PER_PAGE; i++) { pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n", >table[i], @@ -,7 +1113,7 @@ static int pt_buffer_init_topa(struct pt_buffer *buf, int cpu, /* link last table to the first one, unless we're double buffering */ if (intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) { - TOPA_ENTRY(buf->last, -1)->base = buf->first->phys >> TOPA_SHIFT; + TOPA_ENTRY(buf->last, -1)->base = topa_pfn(buf->first); TOPA_ENTRY(buf->last, -1)->end = 1; }
Re: [PATCH] KVM: selftests: Detect max PA width from cpuid
On Mon, Aug 26, 2019 at 07:22:44PM +0800, Peter Xu wrote: > On Mon, Aug 26, 2019 at 01:09:58PM +0200, Andrew Jones wrote: > > On Mon, Aug 26, 2019 at 03:57:28PM +0800, Peter Xu wrote: > > > The dirty_log_test is failing on some old machines like Xeon E3-1220 > > > with tripple faults when writting to the tracked memory region: > > > > > > Test iterations: 32, interval: 10 (ms) > > > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > > > guest physical test memory offset: 0x7fbffef000 > > > Test Assertion Failure > > > dirty_log_test.c:138: false > > > pid=6137 tid=6139 - Success > > > 1 0x00401ca1: vcpu_worker at dirty_log_test.c:138 > > > 2 0x7f3dd9e392dd: ?? ??:0 > > > 3 0x7f3dd9b6a132: ?? ??:0 > > > Invalid guest sync status: exit_reason=SHUTDOWN > > > > > > It's because previously we moved the testing memory region from a > > > static place (1G) to the top of the system's physical address space, > > > meanwhile we stick to 39 bits PA for all the x86_64 machines. That's > > > not true for machines like Xeon E3-1220 where it only supports 36. > > > > > > Let's unbreak this test by dynamically detect PA width from CPUID > > > 0x8008. Meanwhile, even allow kvm_get_supported_cpuid_index() to > > > fail. I don't know whether that could be useful because I think > > > 0x8008 should be there for all x86_64 hosts, but I also think it's > > > not really helpful to assert in the kvm_get_supported_cpuid_index(). > > > > > > Fixes: b442324b581556e > > > CC: Paolo Bonzini > > > CC: Andrew Jones > > > CC: Radim Krčmář > > > CC: Thomas Huth > > > Signed-off-by: Peter Xu > > > --- > > > tools/testing/selftests/kvm/dirty_log_test.c | 22 +-- > > > .../selftests/kvm/lib/x86_64/processor.c | 3 --- > > > 2 files changed, 15 insertions(+), 10 deletions(-) > > > > > > diff --git a/tools/testing/selftests/kvm/dirty_log_test.c > > > b/tools/testing/selftests/kvm/dirty_log_test.c > > > index ceb52b952637..111592f3a1d7 100644 > > > --- a/tools/testing/selftests/kvm/dirty_log_test.c > > > +++ b/tools/testing/selftests/kvm/dirty_log_test.c > > > @@ -274,18 +274,26 @@ static void run_test(enum vm_guest_mode mode, > > > unsigned long iterations, > > > DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode)); > > > > > > #ifdef __x86_64__ > > > - /* > > > - * FIXME > > > - * The x86_64 kvm selftests framework currently only supports a > > > - * single PML4 which restricts the number of physical address > > > - * bits we can change to 39. > > > - */ > > > - guest_pa_bits = 39; > > > + { > > > + struct kvm_cpuid_entry2 *entry; > > > + > > > + entry = kvm_get_supported_cpuid_entry(0x8008); > > > + /* > > > + * Supported PA width can be smaller than 52 even if > > > + * we're with VM_MODE_P52V48_4K mode. Fetch it from > > > > It seems like x86_64 should create modes that actually work, rather than > > always using one named 'P52', but then needing to probe for the actual > > number of supported physical bits. Indeed testing all x86_64 supported > > modes, like aarch64 does, would even make more sense in this test. > > Should be true. I'll think it over again... > > > > > > > > + * the host to update the default value (SDM 4.1.4). > > > + */ > > > + if (entry) > > > + guest_pa_bits = entry->eax & 0xff; > > > > Are we sure > 39 bits will work with this test framework? I can't > > recall what led me to the FIXME above, other than things not working. > > It seems I was convinced we couldn't have more bits due to how pml4's > > were allocated, but maybe I misinterpreted it. > > As mentioned in the IRC - I think I've got a "success case" of > that... :) Please see below: > > virtlab423:~ $ lscpu > Architecture:x86_64 > CPU op-mode(s): 32-bit, 64-bit > Byte Order: Little Endian > CPU(s): 16 > On-line CPU(s) list: 0-15 > Thread(s) per core: 1 > Core(s) per socket: 8 > Socket(s): 2 > NUMA node(s):2 > Vendor ID: GenuineIntel > CPU family: 6 > Model: 63 > Model name: Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz > Stepping:2 > CPU MHz: 2597.168 > BogoMIPS:5194.31 > Virtualization: VT-x > L1d cache: 32K > L1i cache: 32K > L2 cache:256K > L3 cache:20480K > NUMA node0 CPU(s): 0,2,4,6,8,10,12,14 > NUMA node1 CPU(s): 1,3,5,7,9,11,13,15 > Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca > cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx > pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology > nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 ds_cpl vmx smx est tm2 > ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt aes > xsave avx f16c rdrand lahf_lm
Re: [PATCH] powerpc/time: use feature fixup in __USE_RTC() instead of cpu feature.
Christophe Leroy writes: > sched_clock(), used by printk(), calls __USE_RTC() to know > whether to use realtime clock or timebase. > > __USE_RTC() uses cpu_has_feature() which is initialised by > machine_init(). Before machine_init(), __USE_RTC() returns true, > leading to a program check exception on CPUs not having realtime > clock. > > In order to be able to use printk() earlier, use feature fixup. > Feature fixups are applies in early_init(), enabling the use of > printk() earlier. > > Signed-off-by: Christophe Leroy > --- > arch/powerpc/include/asm/time.h | 9 - > 1 file changed, 8 insertions(+), 1 deletion(-) The other option would be just to make this a compile time decision, eg. add CONFIG_PPC_601 and use that to gate whether we use RTC. Given how many 601 users there are, maybe 1?, I think that would be a simpler option and avoids complicating the code / binary for everyone else. cheers > diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h > index 54f4ec1f9fab..3455cb54c333 100644 > --- a/arch/powerpc/include/asm/time.h > +++ b/arch/powerpc/include/asm/time.h > @@ -42,7 +42,14 @@ struct div_result { > /* Accessor functions for the timebase (RTC on 601) registers. */ > /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ > #ifdef CONFIG_PPC_BOOK3S_32 > -#define __USE_RTC() (cpu_has_feature(CPU_FTR_USE_RTC)) > +static inline bool __USE_RTC(void) > +{ > + asm_volatile_goto(ASM_FTR_IFCLR("nop;", "b %1;", %0) :: > + "i" (CPU_FTR_USE_RTC) :: l_use_rtc); > + return false; > +l_use_rtc: > + return true; > +} > #else > #define __USE_RTC() 0 > #endif > -- > 2.13.3
Re: [PATCH V5 1/3] mmc: mmci: add hardware busy timeout feature
On Tue, 13 Aug 2019 at 12:00, Ludovic Barre wrote: > > From: Ludovic Barre > > In some variants, the data timer starts and decrements > when the DPSM enters in Wait_R or Busy state > (while data transfer or MMC_RSP_BUSY), and generates a > data timeout error if the counter reach 0. I don't quite follow here, sorry. Can you please try to elaborate on the use case(s) more exactly? For example, what happens when a data transfer has just finished (for example when MCI_DATAEND has been received) and we are going to send a CMD12 to stop it? In this case the CMD12 has the MMC_RSP_BUSY flag set. Another example is the CMD5, which has no data with it. > > -Define max_busy_timeout (in ms) according to clock. > -Set data timer register if the command has rsp_busy flag. > If busy_timeout is not defined by framework, the busy > length after Data Burst is defined as 1 second > (refer: 4.6.2.2 Write of sd specification part1 v6-0). One second is not sufficient for all operations, like ERASE for example. However, I understand that you want to pick some value, as a safety. I guess that's fine. I am thinking that if the command has the MMC_RSP_BUSY flag set, the core should really provide a busy timeout for it. That said, maybe the host driver should splat a WARN in case there is not busy timeout specified. > -Add MCI_DATATIMEOUT error management in mmci_cmd_irq. > > Signed-off-by: Ludovic Barre > --- > drivers/mmc/host/mmci.c | 37 - > drivers/mmc/host/mmci.h | 3 +++ > 2 files changed, 35 insertions(+), 5 deletions(-) > > diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c > index c37e70dbe250..c50586540765 100644 > --- a/drivers/mmc/host/mmci.c > +++ b/drivers/mmc/host/mmci.c > @@ -1075,6 +1075,7 @@ static void > mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) > { > void __iomem *base = host->base; > + unsigned long long clks = 0; > > dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", > cmd->opcode, cmd->arg, cmd->flags); > @@ -1097,6 +1098,19 @@ mmci_start_command(struct mmci_host *host, struct > mmc_command *cmd, u32 c) > else > c |= host->variant->cmdreg_srsp; > } > + > + if (host->variant->busy_timeout && !host->mrq->data) { Suppose this is a CMD12 command, having the MMC_RSP_BUSY flag set. The command would then be sent to stop the transmission and then host->mrq->data would also be set. If I recall earlier what you stated about the new sdmmc variant, the CMD12 is needed to exit the DPSM. Hence don't you need to re-program a new value for the MMCIDATATIMER register for this scenario? > + if (cmd->flags & MMC_RSP_BUSY) { > + if (!cmd->busy_timeout) > + cmd->busy_timeout = 1000; > + > + clks = (unsigned long long)cmd->busy_timeout; > + clks *= host->cclk; Any problems with putting the above on one line? > + do_div(clks, MSEC_PER_SEC); > + } > + writel_relaxed(clks, host->base + MMCIDATATIMER); This is writing zero to MMCIDATATIMER in case the MMC_RSP_BUSY isn't set, is that on purpose? > + } > + > if (/*interrupt*/0) > c |= MCI_CPSM_INTERRUPT; > > @@ -1203,6 +1217,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command > *cmd, > { > void __iomem *base = host->base; > bool sbc, busy_resp; > + u32 err_msk; > > if (!cmd) > return; > @@ -1215,8 +1230,12 @@ mmci_cmd_irq(struct mmci_host *host, struct > mmc_command *cmd, > * handling. Note that we tag on any latent IRQs postponed > * due to waiting for busy status. > */ > - if (!((status|host->busy_status) & > - (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND))) > + err_msk = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT; You might as well move the initial assignment of err_msk to the its declaration above. > + if (host->variant->busy_timeout && busy_resp) > + err_msk |= MCI_DATATIMEOUT; > + > + if (!((status | host->busy_status) & > + (err_msk | MCI_CMDSENT | MCI_CMDRESPEND))) > return; > > /* Handle busy detection on DAT0 if the variant supports it. */ > @@ -1235,8 +1254,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command > *cmd, > * while, to allow it to be set, but tests indicates that it > * isn't needed. > */ > - if (!host->busy_status && > - !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && > + if (!host->busy_status && !(status & err_msk) && > (readl(base + MMCISTATUS) & > host->variant->busy_detect_flag)) { > > writel(readl(base + MMCIMASK0) | > @@ -1290,6 +1308,9 @@
Re: [PATCH] KVM: selftests: Detect max PA width from cpuid
On Mon, Aug 26, 2019 at 06:47:57PM +0800, Peter Xu wrote: > On Mon, Aug 26, 2019 at 10:25:55AM +0200, Vitaly Kuznetsov wrote: > > Peter Xu writes: > > > > > The dirty_log_test is failing on some old machines like Xeon E3-1220 > > > with tripple faults when writting to the tracked memory region: > > > > s,writting,writing, > > > > > > > > Test iterations: 32, interval: 10 (ms) > > > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > > > guest physical test memory offset: 0x7fbffef000 > > > Test Assertion Failure > > > dirty_log_test.c:138: false > > > pid=6137 tid=6139 - Success > > > 1 0x00401ca1: vcpu_worker at dirty_log_test.c:138 > > > 2 0x7f3dd9e392dd: ?? ??:0 > > > 3 0x7f3dd9b6a132: ?? ??:0 > > > Invalid guest sync status: exit_reason=SHUTDOWN > > > > > > > This patch breaks on my AMD machine with > > > > # cpuid -1 -l 0x8008 > > CPU: > >Physical Address and Linear Address Size (0x8008/eax): > > maximum physical address bits = 0x30 (48) > > maximum linear (virtual) address bits = 0x30 (48) > > maximum guest physical address bits = 0x0 (0) > > > > > > Pre-patch: > > > > # ./dirty_log_test > > Test iterations: 32, interval: 10 (ms) > > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > > guest physical test memory offset: 0x7fbffef000 > > Dirtied 139264 pages > > Total bits checked: dirty (135251), clear (7991709), track_next (29789) > > > > Post-patch: > > > > # ./dirty_log_test > > Test iterations: 32, interval: 10 (ms) > > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > > Supported guest physical address width: 48 > > guest physical test memory offset: 0xbffef000 > > Test Assertion Failure > > dirty_log_test.c:141: false > > pid=77983 tid=77985 - Success > > 1 0x00401d12: vcpu_worker at dirty_log_test.c:138 > > 2 0x7f636374358d: ?? ??:0 > > 3 0x7f63636726a2: ?? ??:0 > > Invalid guest sync status: exit_reason=SHUTDOWN > > Vitaly, > > Are you using shadow paging? If so, could you try NPT=off? Sorry, it should be s/shadow paging/NPT/... [root@hp-dl385g10-10 peter]# ./dirty_log_test Test iterations: 32, interval: 10 (ms) Testing guest mode: PA-bits:52, VA-bits:48, 4K pages Supported guest physical address width: 48 guest physical test memory offset: 0xbffef000 Test Assertion Failure dirty_log_test.c:138: false pid=5433 tid=5436 - Success 1 0x00401cc1: vcpu_worker at dirty_log_test.c:138 2 0x7f18977992dd: ?? ??:0 3 0x7f18974ca132: ?? ??:0 Invalid guest sync status: exit_reason=SHUTDOWN [root@hp-dl385g10-10 peter]# modprobe -r kvm_amd [root@hp-dl385g10-10 peter]# modprobe kvm_amd npt=0 [root@hp-dl385g10-10 peter]# ./dirty_log_test Test iterations: 32, interval: 10 (ms) Testing guest mode: PA-bits:52, VA-bits:48, 4K pages Supported guest physical address width: 48 guest physical test memory offset: 0xbffef000 Dirtied 102400 pages Total bits checked: dirty (99021), clear (8027939), track_next (23425) > > I finally found a AMD host and I also found that it's passing with > shadow MMU mode which is strange. If so I would suspect it's a real > bug in AMD NTP path but I'd like to see whether it's also happening on > your side. > > Thanks, -- Peter Xu
Re: [RFC 1/9] dt-bindings: arm: samsung: Convert Samsung board/soc bindings to json-schema
On Fri, Aug 23, 2019 at 9:54 AM Krzysztof Kozlowski wrote: > > Convert Samsung S5P and Exynos SoC bindings to DT schema format using > json-schema. This is purely conversion of already documented bindings > so it does not cover all of DTS in the Linux kernel (few S5P/Exynos and > all S3C are missing). > > Signed-off-by: Krzysztof Kozlowski > > --- > > If the schema looks sensible, I will continue on converting other > SoC and driver bindings and later adding missing schemas (S3C > SoCs). Looks pretty good. > --- > .../bindings/arm/samsung/samsung-boards.txt | 83 > .../bindings/arm/samsung/samsung-boards.yaml | 188 ++ > 2 files changed, 188 insertions(+), 83 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt > create mode 100644 > Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml > diff --git > a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml > b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml > new file mode 100644 > index ..e963fd70c436 > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml > @@ -0,0 +1,188 @@ > +# SPDX-License-Identifier: GPL-2.0 > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/arm/samsung/samsung-boards.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Samsung Exynos and S5P SoC based boards > + > +maintainers: > + - Krzysztof Kozlowski > + > +properties: > + $nodename: > +const: '/' > + compatible: > +oneOf: > + - description: S5PV210 based Aries boards > +items: > + - enum: > + - samsung,fascinate4g # Samsung Galaxy S Fascinate > 4G (SGH-T959P) > + - samsung,galaxys # Samsung Galaxy S (i9000) > + - const: samsung,aries > + - const: samsung,s5pv210 > + > + - description: Exynos3250 based boards > +items: > + - enum: > + - samsung,monk# Samsung Simband > + - samsung,rinato # Samsung Gear2 > + - const: samsung,exynos3250 > + - const: samsung,exynos3 > + > + - description: Samsung ARTIK5 boards > +items: > + - enum: > + - samsung,artik5-eval # Samsung ARTIK5 eval board > + - const: samsung,artik5 # Samsung ARTIK5 module > + - const: samsung,exynos3250 > + - const: samsung,exynos3 > + > + - description: Exynos4210 based boards > +items: > + - enum: > + - insignal,origen # Insignal Origen > + - samsung,smdkv310# Samsung SMDKV310 eval > + - samsung,trats # Samsung Tizen Reference > + - samsung,universal_c210 # Samsung C210 > + - const: samsung,exynos4210 > + - const: samsung,exynos4 > + > + - description: Exynos4412 based boards > +items: > + - enum: > + - friendlyarm,tiny4412# FriendlyARM TINY4412 > + - hardkernel,odroid-u3# Hardkernel Odroid U3 > + - hardkernel,odroid-x # Hardkernel Odroid X > + - hardkernel,odroid-x2# Hardkernel Odroid X2 > + - insignal,origen4412 # Insignal Origen > + - samsung,smdk4412# Samsung SMDK4412 eval > + - topeet,itop4412-elite # TOPEET Elite base > + - const: samsung,exynos4412 > + - const: samsung,exynos4 > + > + - description: Samsung Midas family boards > +items: > + - enum: > + - samsung,i9300 # Samsung GT-I9300 > + - samsung,i9305 # Samsung GT-I9305 > + - samsung,n710x # Samsung GT-N7100/GT-N7105 > + - samsung,trats2 # Samsung Tizen Reference > + - const: samsung,midas > + - const: samsung,exynos4412 > + - const: samsung,exynos4 > + > + - description: Exynos5250 based boards > +items: > + - enum: > + - google,snow-rev5# Google Snow Rev 5+ > + - google,spring # Google Spring > + - insignal,arndale# Insignal Arndale > + - samsung,smdk5250# Samsung SMDK5250 eval > + - const: samsung,exynos5250 > + - const: samsung,exynos5 > + > + - description: Google Snow Boards (Rev 4+) > +items: > + - enum: > + - google,snow-rev4 const here as I wouldn't expect this list to grow. > + - const: google,snow > + - const: samsung,exynos5250 > + - const: samsung,exynos5 > + > + - description: Exynos5260
BoF on LPC 2019 : Linux Perf advancements for compute intensive and server systems
Hi, There is a BoF session scheduled on Linux Plumbers Conference 2019 event. If you plan attend the event feel free to join and discuss about the BoF topic and beyond: Linux Perf advancements for compute intensive and server systems: "Modern server and compute intensive systems are naturally built around several top performance CPUs with large amount of cores and equipped by shared memory that spans a number of NUMA domains. Compute intensive workloads usually implement highly parallel CPU bound cyclic codes performing mathematics calculations that reference data located in the shared memory. Performance observability and profiling of these workloads on such systems have unique characteristics and impose specific requirements on software performance tools. The requirements include tools CPU scalability, coping with high rate and volume of collected performance data as well as NUMA awareness. In order to fulfill that requirements a number of extensions have been implemented in Linux Perf tool that are currently a part of the Linux kernel source tree [1], [2], [3], [4]" Best regards, Alexey [1] https://marc.info/?l=linux-kernel=154149439404555=2 [2] https://marc.info/?l=linux-kernel=154817912621465=2 [3] https://marc.info/?l=linux-kernel=155293062518459=2 [4] https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html
Re: [PATCH] riscv: add arch/riscv/Kbuild
On Wed, Aug 21, 2019 at 06:26:58PM +0900, Masahiro Yamada wrote: > Use the standard obj-y form to specify the sub-directories under > arch/riscv/. No functional change intended. > > Signed-off-by: Masahiro Yamada Do you have a document what the grand scheme here is? Less of the magic in arch/$(ARCH)/Makefile sounds like a good idea, but unless we have a very specific split between the kbuild makefile and various override I fear just splitting things up into two files doesn't really help much.
Re: [PATCH] KVM: selftests: Detect max PA width from cpuid
Peter Xu writes: > On Mon, Aug 26, 2019 at 10:25:55AM +0200, Vitaly Kuznetsov wrote: >> Peter Xu writes: >> >> > The dirty_log_test is failing on some old machines like Xeon E3-1220 >> > with tripple faults when writting to the tracked memory region: >> >> s,writting,writing, >> >> > >> > Test iterations: 32, interval: 10 (ms) >> > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages >> > guest physical test memory offset: 0x7fbffef000 >> > Test Assertion Failure >> > dirty_log_test.c:138: false >> > pid=6137 tid=6139 - Success >> > 1 0x00401ca1: vcpu_worker at dirty_log_test.c:138 >> > 2 0x7f3dd9e392dd: ?? ??:0 >> > 3 0x7f3dd9b6a132: ?? ??:0 >> > Invalid guest sync status: exit_reason=SHUTDOWN >> > >> >> This patch breaks on my AMD machine with >> >> # cpuid -1 -l 0x8008 >> CPU: >>Physical Address and Linear Address Size (0x8008/eax): >> maximum physical address bits = 0x30 (48) >> maximum linear (virtual) address bits = 0x30 (48) >> maximum guest physical address bits = 0x0 (0) >> >> >> Pre-patch: >> >> # ./dirty_log_test >> Test iterations: 32, interval: 10 (ms) >> Testing guest mode: PA-bits:52, VA-bits:48, 4K pages >> guest physical test memory offset: 0x7fbffef000 >> Dirtied 139264 pages >> Total bits checked: dirty (135251), clear (7991709), track_next (29789) >> >> Post-patch: >> >> # ./dirty_log_test >> Test iterations: 32, interval: 10 (ms) >> Testing guest mode: PA-bits:52, VA-bits:48, 4K pages >> Supported guest physical address width: 48 >> guest physical test memory offset: 0xbffef000 >> Test Assertion Failure >> dirty_log_test.c:141: false >> pid=77983 tid=77985 - Success >> 1 0x00401d12: vcpu_worker at dirty_log_test.c:138 >> 2 0x7f636374358d: ?? ??:0 >> 3 0x7f63636726a2: ?? ??:0 >> Invalid guest sync status: exit_reason=SHUTDOWN > > Vitaly, > > Are you using shadow paging? If so, could you try NPT=off? > Yep, test passes with shadow paging, fails when NPT is enabled. > I finally found a AMD host and I also found that it's passing with > shadow MMU mode which is strange. If so I would suspect it's a real > bug in AMD NTP path but I'd like to see whether it's also happening on > your side. Sounds like a bug indeed. -- Vitaly
Re: [PATCH] x86/mm: Do not split_large_page() for set_kernel_text_rw()
On Fri, 23 Aug 2019 11:36:37 +0200 Peter Zijlstra wrote: > On Thu, Aug 22, 2019 at 10:23:35PM -0700, Song Liu wrote: > > As 4k pages check was removed from cpa [1], set_kernel_text_rw() leads to > > split_large_page() for all kernel text pages. This means a single kprobe > > will put all kernel text in 4k pages: > > > > root@ ~# grep 8100- /sys/kernel/debug/page_tables/kernel > > 0x8100-0x8240 20M roPSE x pmd > > > > root@ ~# echo ONE_KPROBE >> /sys/kernel/debug/tracing/kprobe_events > > root@ ~# echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable > > > > root@ ~# grep 8100- /sys/kernel/debug/page_tables/kernel > > 0x8100-0x8240 20M ro x pte > > > > To fix this issue, introduce CPA_FLIP_TEXT_RW to bypass "Text RO" check > > in static_protections(). > > > > Two helper functions set_text_rw() and set_text_ro() are added to flip > > _PAGE_RW bit for kernel text. > > > > [1] commit 585948f4f695 ("x86/mm/cpa: Avoid the 4k pages check completely") > > > > ARGH; so this is because ftrace flips the whole kernel range to RW and > back for giggles? I'm thinking _that_ is a bug, it's a clear W^X > violation. Since ftrace did this way before text_poke existed and way before anybody cared (back in 2007), it's not really a bug. Anyway, I believe Nadav has some patches that converts ftrace to use the shadow page modification trick somewhere. Or we also need the text_poke batch processing (did that get upstream?). Mapping in 40,000 pages one at a time is noticeable from a human stand point. -- Steve
Re: [PATCH] tpm: tpm_crb: Fix an improper buffer size calculation bug
On Mon, Aug 26, 2019 at 04:44:00PM +0900, Seunghun Han wrote: > I'm Seunghun Han and work at the Affiliated Institute of ETRI. I found You can drop the first sentence from the commit message. The SoB below is sufficient. > a bug related to improper buffer size calculation in crb_fixup_cmd_size > function. The purpose is to cap to the ACPI region when we partially overlap to workaround BIOS's reporting corrupted ACPI tables so that we don't get failure from devm_ioremap(). The only funky thing in that function is that it lets through a buffer that is fully outside the ACPI region. There actually exists hardware with this configuration. > When the TPM CRB regions are two or more, the crb_map_io function calls > crb_fixup_cmd_size twice to calculate command buffer size and response > buffer size. The purpose of crb_fixup_cmd_size function is to trust > the ACPI region information. This is not true. The driver deals with only one ACPI region ATM. > However, the function compares only io_res argument with start and size > arguments. It means the io_res argument is one of command buffer and > response buffer regions. It also means the other region is not calculated > correctly by the function because io_res argument doesn't cover all TPM > CRB regions. The driver gets command and response buffer metrics from the TPM2 ACPI table, not from the ACPI region. > To fix this bug, I change crb_check_resource function for storing all TPB > CRB regions to a list and use the list to calculate command buffer size > and response buffer size correctly. This cannot be categorized as a bug. It is simply as new type of hardware. Can you explain in detail what type of hardware are you using? > --- > drivers/char/tpm/tpm_crb.c | 50 ++ > 1 file changed, 34 insertions(+), 16 deletions(-) > > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c > index e59f1f91d7f3..b0e94e02e5eb 100644 > --- a/drivers/char/tpm/tpm_crb.c > +++ b/drivers/char/tpm/tpm_crb.c > @@ -442,6 +442,9 @@ static int crb_check_resource(struct acpi_resource *ares, > void *data) > acpi_dev_resource_address_space(ares, )) { > *io_res = *res; > io_res->name = NULL; > + > + /* Add this TPM CRB resource to the list */ > + return 0; > } > > return 1; > @@ -471,20 +474,30 @@ static void __iomem *crb_map_res(struct device *dev, > struct crb_priv *priv, > * region vs the registers. Trust the ACPI region. Such broken systems > * probably cannot send large TPM commands since the buffer will be > truncated. > */ > -static u64 crb_fixup_cmd_size(struct device *dev, struct resource *io_res, > +static u64 crb_fixup_cmd_size(struct device *dev, struct list_head > *resources, > u64 start, u64 size) With a quick spin w/o knowing the details of the hardware I'm dealing with it you should probably reduce the fixup function as static u64 crb_fixup_cmd_size(struct device *dev, struct resource *io_res, u64 start, u64 size) { if (start + size - 1 <= io_res->end) return size; dev_err(dev, FW_BUG "ACPI region does not cover the entire command/response buffer. %pr vs %llx %llx\n", io_res, start, size); return io_res->end - start + 1; } Then call this inside the loop. Looking at your change it does not make much sense to me. There is a weird asymmetry in it: 1. The code loops through all found ACPI regions when looking for intersections with the command and response buffers. 2. The devm_ioremap() is done only to the last seen ACPI region. Why the multiple regions matter for fixup's but not in this case? /Jarkko
[PATCH] media: em28xx: Fix exception handling in em28xx_alloc_urbs()
From: Markus Elfring Date: Mon, 26 Aug 2019 13:14:02 +0200 A null pointer would be passed to a call of the function "kfree" directly after a call of the function "kcalloc" failed at one place. Pass the data structure member "urb" instead for which memory was allocated before (so that this resource will be properly cleaned up). This issue was detected by using the Coccinelle software. Fixes: d571b592c6206d33731f41aa710fa0f69ac8611b ("media: em28xx: don't use coherent buffer for DMA transfers") Signed-off-by: Markus Elfring --- drivers/media/usb/em28xx/em28xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 2b8c84a5c9a8..e6088b5d1b80 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -931,7 +931,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->buf = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!usb_bufs->buf) { - kfree(usb_bufs->buf); + kfree(usb_bufs->urb); return -ENOMEM; } -- 2.23.0
Re: [PATCH] sched/cpufreq: Align trace event behavior of fast switching
On Mon, Aug 26, 2019 at 11:51:17AM +0200, Dietmar Eggemann wrote: > Not sure about the extra 'if trace_cpu_frequency_enabled()' but I guess > it doesn't hurt. Without that you do that for_each_cpu() iteration unconditionally, even if the tracepoint is disabled.
Re: [PATCH v2 1/2] dt-bindings: reset: Add YAML schemas for the Intel Reset controller
On Mon, Aug 26, 2019 at 4:52 AM Dilip Kota wrote: > > Hi Rob, > > On 8/23/2019 8:25 PM, Rob Herring wrote: > > On Fri, Aug 23, 2019 at 12:28 AM Dilip Kota > > wrote: > >> Add YAML schemas for the reset controller on Intel > >> Lightening Mountain (LGM) SoC. > >> > >> Signed-off-by: Dilip Kota > >> --- > >> Changes on v2: > >> Address review comments > >>Update the compatible property definition > >>Add description for reset-cells > >>Add 'additionalProperties: false' property > >> > >> .../bindings/reset/intel,syscon-reset.yaml | 53 > >> ++ > >> 1 file changed, 53 insertions(+) > >> create mode 100644 > >> Documentation/devicetree/bindings/reset/intel,syscon-reset.yaml > >> > >> diff --git > >> a/Documentation/devicetree/bindings/reset/intel,syscon-reset.yaml > >> b/Documentation/devicetree/bindings/reset/intel,syscon-reset.yaml > >> new file mode 100644 > >> index ..3403a967190a > >> --- /dev/null > >> +++ b/Documentation/devicetree/bindings/reset/intel,syscon-reset.yaml > >> @@ -0,0 +1,53 @@ > >> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > >> +%YAML 1.2 > >> +--- > >> +$id: http://devicetree.org/schemas/reset/intel,syscon-reset.yaml# > >> +$schema: http://devicetree.org/meta-schemas/core.yaml# > >> + > >> +title: Intel Lightening Mountain SoC System Reset Controller > >> + > >> +maintainers: > >> + - Dilip Kota > >> + > >> +properties: > >> + compatible: > >> +items: > >> + - const: intel,rcu-lgm > >> + - const: syscon > >> + > >> + reg: > >> +description: Reset controller register base address and size > >> + > >> + intel,global-reset: > >> +$ref: /schemas/types.yaml#/definitions/uint32-array > >> +description: Global reset register offset and bit offset. > >> + > >> + "#reset-cells": > >> +const: 2 > >> +description: | > >> + The 1st cell is the register offset. > >> + The 2nd cell is the bit offset in the register. > >> + > >> +required: > >> + - compatible > >> + - reg > >> + - intel,global-reset > >> + - "#reset-cells" > >> + > >> +additionalProperties: false > >> + > >> +examples: > >> + - | > >> +rcu0: reset-controller@ { > >> +compatible = "intel,rcu-lgm", "syscon"; > >> +reg = <0x00 0x8>; > >> +intel,global-reset = <0x10 30>; > >> +#reset-cells = <2>; > >> +}; > >> + > >> +pcie_phy0: pciephy@... { > >> +... > > You need to run 'make dt_binding_check' and fix the warnings. The > > example has to be buildable and it is not. > > Sure, i will correct this pcie_phy0 node. But i didn't get any warnings > for make dt_binding_check > >CHKDT Documentation/devicetree/bindings/reset/intel,syscon-reset.yaml > DTC Documentation/devicetree/bindings/arm/renesas.example.dt.yaml > FATAL ERROR: Unknown output format "yaml" > > Will DTC report about the example node errors? But, DTC is failing with > FATAL_ERROR. > I tried it even after installing libyaml and headers in my local > directory and export the path, but no luck.(ref: > https://lkml.org/lkml/2018/12/3/951) > Could you please let me know if i miss anything and help me to proceed > further. See Documentation/devicetree/writing-schema.md Rob
Re: [PATCH] KVM: selftests: Detect max PA width from cpuid
On Mon, Aug 26, 2019 at 01:09:58PM +0200, Andrew Jones wrote: > On Mon, Aug 26, 2019 at 03:57:28PM +0800, Peter Xu wrote: > > The dirty_log_test is failing on some old machines like Xeon E3-1220 > > with tripple faults when writting to the tracked memory region: > > > > Test iterations: 32, interval: 10 (ms) > > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > > guest physical test memory offset: 0x7fbffef000 > > Test Assertion Failure > > dirty_log_test.c:138: false > > pid=6137 tid=6139 - Success > > 1 0x00401ca1: vcpu_worker at dirty_log_test.c:138 > > 2 0x7f3dd9e392dd: ?? ??:0 > > 3 0x7f3dd9b6a132: ?? ??:0 > > Invalid guest sync status: exit_reason=SHUTDOWN > > > > It's because previously we moved the testing memory region from a > > static place (1G) to the top of the system's physical address space, > > meanwhile we stick to 39 bits PA for all the x86_64 machines. That's > > not true for machines like Xeon E3-1220 where it only supports 36. > > > > Let's unbreak this test by dynamically detect PA width from CPUID > > 0x8008. Meanwhile, even allow kvm_get_supported_cpuid_index() to > > fail. I don't know whether that could be useful because I think > > 0x8008 should be there for all x86_64 hosts, but I also think it's > > not really helpful to assert in the kvm_get_supported_cpuid_index(). > > > > Fixes: b442324b581556e > > CC: Paolo Bonzini > > CC: Andrew Jones > > CC: Radim Krčmář > > CC: Thomas Huth > > Signed-off-by: Peter Xu > > --- > > tools/testing/selftests/kvm/dirty_log_test.c | 22 +-- > > .../selftests/kvm/lib/x86_64/processor.c | 3 --- > > 2 files changed, 15 insertions(+), 10 deletions(-) > > > > diff --git a/tools/testing/selftests/kvm/dirty_log_test.c > > b/tools/testing/selftests/kvm/dirty_log_test.c > > index ceb52b952637..111592f3a1d7 100644 > > --- a/tools/testing/selftests/kvm/dirty_log_test.c > > +++ b/tools/testing/selftests/kvm/dirty_log_test.c > > @@ -274,18 +274,26 @@ static void run_test(enum vm_guest_mode mode, > > unsigned long iterations, > > DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode)); > > > > #ifdef __x86_64__ > > - /* > > -* FIXME > > -* The x86_64 kvm selftests framework currently only supports a > > -* single PML4 which restricts the number of physical address > > -* bits we can change to 39. > > -*/ > > - guest_pa_bits = 39; > > + { > > + struct kvm_cpuid_entry2 *entry; > > + > > + entry = kvm_get_supported_cpuid_entry(0x8008); > > + /* > > +* Supported PA width can be smaller than 52 even if > > +* we're with VM_MODE_P52V48_4K mode. Fetch it from > > It seems like x86_64 should create modes that actually work, rather than > always using one named 'P52', but then needing to probe for the actual > number of supported physical bits. Indeed testing all x86_64 supported > modes, like aarch64 does, would even make more sense in this test. Should be true. I'll think it over again... > > > > +* the host to update the default value (SDM 4.1.4). > > +*/ > > + if (entry) > > + guest_pa_bits = entry->eax & 0xff; > > Are we sure > 39 bits will work with this test framework? I can't > recall what led me to the FIXME above, other than things not working. > It seems I was convinced we couldn't have more bits due to how pml4's > were allocated, but maybe I misinterpreted it. As mentioned in the IRC - I think I've got a "success case" of that... :) Please see below: virtlab423:~ $ lscpu Architecture:x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 16 On-line CPU(s) list: 0-15 Thread(s) per core: 1 Core(s) per socket: 8 Socket(s): 2 NUMA node(s):2 Vendor ID: GenuineIntel CPU family: 6 Model: 63 Model name: Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz Stepping:2 CPU MHz: 2597.168 BogoMIPS:5194.31 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache:256K L3 cache:20480K NUMA node0 CPU(s): 0,2,4,6,8,10,12,14 NUMA node1 CPU(s): 1,3,5,7,9,11,13,15 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb invpcid_single pti tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc dtherm arat pln pts virtlab423:~ $ ./dirty_log_test Test iterations: 32,
Re: [PATCH v2] nvme: allow 64-bit results in passthru commands
- On 22 Aug, 2019, at 02:06, Christoph Hellwig h...@lst.de wrote: > On Fri, Aug 16, 2019 at 11:47:21AM +0200, Marta Rybczynska wrote: >> It is not possible to get 64-bit results from the passthru commands, >> what prevents from getting for the Capabilities (CAP) property value. >> >> As a result, it is not possible to implement IOL's NVMe Conformance >> test 4.3 Case 1 for Fabrics targets [1] (page 123). >> >> This issue has been already discussed [2], but without a solution. >> >> This patch solves the problem by adding new ioctls with a new >> passthru structure, including 64-bit results. The older ioctls stay >> unchanged. > > Ok, with my idea not being suitable I think I'm fine with this approach, a > little nitpick below: > >> +static bool is_admin_cmd(unsigned int cmd) >> +{ >> +if ((cmd == NVME_IOCTL_ADMIN_CMD) || (cmd == NVME_IOCTL_ADMIN64_CMD)) >> +return true; >> +return false; >> +} > > No need for the inner braces. But I'm actually not sure the current > code structure is very suitable for extending it. > >> + >> static int nvme_ioctl(struct block_device *bdev, fmode_t mode, >> unsigned int cmd, unsigned long arg) >> { >> @@ -1418,13 +1473,13 @@ static int nvme_ioctl(struct block_device *bdev, >> fmode_t >> mode, >> * seperately and drop the ns SRCU reference early. This avoids a >> * deadlock when deleting namespaces using the passthrough interface. >> */ >> -if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) { >> +if (is_admin_cmd(cmd) || is_sed_ioctl(cmd)) { > > So maybe for this check we should have a is_ctrl_iocl() helper instead > that includes the is_sed_ioctl check. > >> struct nvme_ctrl *ctrl = ns->ctrl; >> >> nvme_get_ctrl(ns->ctrl); >> nvme_put_ns_from_disk(head, srcu_idx); >> >> -if (cmd == NVME_IOCTL_ADMIN_CMD) >> +if (is_admin_cmd(cmd)) >> ret = nvme_user_cmd(ctrl, NULL, argp); >> else >> ret = sed_ioctl(ctrl->opal_dev, cmd, argp); > > And then we can move this whole branch into a helper function, > which then switches on the ioctl cmd, with sed_ioctl as the fallback. Do you mean something like this? +static bool is_ctrl_ioctl(unsigned int cmd) +{ + if (cmd == NVME_IOCTL_ADMIN_CMD || cmd == NVME_IOCTL_ADMIN64_CMD) + return true; + if (is_sed_ioctl(cmd)) + return true; + return false; +} + +static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd, + void __user *argp, + struct nvme_ns_head *head, + int srcu_idx) +{ + struct nvme_ctrl *ctrl = ns->ctrl; + int ret; + + nvme_get_ctrl(ns->ctrl); + nvme_put_ns_from_disk(head, srcu_idx); + + switch (cmd) { + case NVME_IOCTL_ADMIN_CMD: + ret = nvme_user_cmd(ctrl, NULL, argp); + break; + case NVME_IOCTL_ADMIN64_CMD: + ret = nvme_user_cmd64(ctrl, NULL, argp); + break; + default: + ret = sed_ioctl(ctrl->opal_dev, cmd, argp); + break; + } + nvme_put_ctrl(ctrl); + return ret; +} + static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { @@ -1418,20 +1501,8 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, * seperately and drop the ns SRCU reference early. This avoids a * deadlock when deleting namespaces using the passthrough interface. */ - if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) { - struct nvme_ctrl *ctrl = ns->ctrl; - - nvme_get_ctrl(ns->ctrl); - nvme_put_ns_from_disk(head, srcu_idx); - - if (cmd == NVME_IOCTL_ADMIN_CMD) - ret = nvme_user_cmd(ctrl, NULL, argp); - else - ret = sed_ioctl(ctrl->opal_dev, cmd, argp); - - nvme_put_ctrl(ctrl); - return ret; - } + if (is_ctrl_ioctl(cmd)) + return nvme_handle_ctrl_ioctl(ns, cmd, argp, head, srcu_idx); switch (cmd) { case NVME_IOCTL_ID: Regards, Marta
[PATCH v11 1/6] dt-bindings: add binding for USBSS-DRD controller.
This patch aim at documenting USB related dt-bindings for the Cadence USBSS-DRD controller. Signed-off-by: Pawel Laszczak Reviewed-by: Rob Herring --- .../devicetree/bindings/usb/cdns-usb3.txt | 45 +++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/cdns-usb3.txt diff --git a/Documentation/devicetree/bindings/usb/cdns-usb3.txt b/Documentation/devicetree/bindings/usb/cdns-usb3.txt new file mode 100644 index ..b7dc606d37b5 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/cdns-usb3.txt @@ -0,0 +1,45 @@ +Binding for the Cadence USBSS-DRD controller + +Required properties: + - reg: Physical base address and size of the controller's register areas. +Controller has 3 different regions: +- HOST registers area +- DEVICE registers area +- OTG/DRD registers area + - reg-names - register memory area names: + "xhci" - for HOST registers space + "dev" - for DEVICE registers space + "otg" - for OTG/DRD registers space + - compatible: Should contain: "cdns,usb3" + - interrupts: Interrupts used by cdns3 controller: + "host" - interrupt used by XHCI driver. + "peripheral" - interrupt used by device driver + "otg" - interrupt used by DRD/OTG part of driver + +Optional properties: + - maximum-speed : valid arguments are "super-speed", "high-speed" and + "full-speed"; refer to usb/generic.txt + - dr_mode: Should be one of "host", "peripheral" or "otg". + - phys: reference to the USB PHY + - phy-names: from the *Generic PHY* bindings; + Supported names are: + - cdns3,usb2-phy + - cdns3,usb3-phy + + - cdns,on-chip-buff-size : size of memory intended as internal memory for endpoints + buffers expressed in KB + +Example: + usb@f300 { + compatible = "cdns,usb3"; + interrupts = , + , + ; + interrupt-names = "host", "peripheral", "otg"; + reg = <0xf300 0x1>, /* memory area for HOST registers */ + <0xf301 0x1>, /* memory area for DEVICE registers */ + <0xf302 0x1>; /* memory area for OTG/DRD registers */ + reg-names = "xhci", "dev", "otg"; + phys = <_phy>, <_phy>; + phy-names = "cdns3,usb2-phy", "cnds3,usb3-phy"; + }; -- 2.17.1
[PATCH v11 0/6] Introduced new Cadence USBSS DRD Driver.
This patch introduce new Cadence USBSS DRD driver to linux kernel. The Cadence USBSS DRD Controller is a highly configurable IP Core which can be instantiated as Dual-Role Device (DRD), Peripheral Only and Host Only (XHCI)configurations. The current driver has been validated with FPGA burned. We have support for PCIe bus, which is used on FPGA prototyping. The host side of USBSS-DRD controller is compliance with XHCI specification, so it works with standard XHCI Linux driver. Changes since v10: - Moved handling of usb_ists interrupts to thread handler. - Removed no longer needed shadow_ep_en field from cdns3_device structure. - Removed choosing the role by debugfs. - Added support for forcing controller speed. - Fixed issue with changing kind of access to memory. - Set quirk_avoids_skb_reserve. - Fixed issue related with phy initialization in cdns3_probe. - Fixed address of dma_axi_ctrl register. - Improved role switch implementation as suggested by Roger. - Fixed issue with handling STALL. - Some other minor change sugested by Felipe and Roger. Changes since v9: - Removed duplicated cdns3_mode array. The same array is defined in drivers/usb/common/common.c. It required some change in common API. the appropirate patch was posted separately. - Replaced generic cdns3_dbg with serparate trace events. - Replaced cdns3_handshake with readl_poll_timeout_atomic function - Added threaded irq handler for handling DRD/OTG irq instead workqueue. - Removed support for debug_disable. It's no longer neeeded. - Moved mode attribute under usb root. - Changed DRD switching role implementation. This version of the driver uses common roles interface. - removed not implemented cdns3_idle_role_start and cdns3_exit_role_start. - Added support for DRD/OTG irq for Cadence platform. - Fixed bug in cdns3_mode_show/cdns3_mode_write with changing mode. There was a problem with switching mode. - Added support for PM suspend/resume. - Simplified cdns3/Makefile file. Changes since v8: - Fixed compilation error by moving drivers/usb/gadget/debug.c back to drivers/usb/common/debug.c. The previous version caused compilation error when dwc3 or cdns3 driver was built-in kernel and libcomposite was built as module. Changes since v7: - Updated dt-binding. - Simplified debugfs file as suggested by Heikki Krogerus. - Changed some dev_info to dev_dbg. - Added support for additional PHY. Now driver can use both USB2 PHY and USB3 PHY. - Fixed issue in algorithm checking the number of allocated on-chip buffers. - Moved common code form drivers/usb/common/debug.c to drivers/usb/gadget/debug.c. - Removed warning generated by sh4-linux-gcc compiler for trace.h file. - L1 issue: moved resuming after setting DRDY. It should protect against potential racing. - LPM packet acknowledge has been disabled during control transfer. - Aded setting AXI Non-Secure mode in DMA_AXI_CTRL register. Changes since v6: - Fixed issue with L1 support. Controller has issue with hardware resuming from L1 state. It was fixed in software. - Fixed issues related with Transfer Ring Size equal 2. - Fixed issue with removing cdns3.ko module. Issue appeared on the latest version of kernel. - Added separate interrupt resources for host, device and otg. It was added mainly for compatibility with TI platforms. - Added enabling ISO OUT just before arming endpoint. It's recommended by controller specification. - Added support for 0x0002450d controller version. This version allows to set DMULT mode per endpoint. It also fixes WA1 issue. - Added support for separate interrupt line for Device and OTG/DRD. - Removed drd_update_mode from drd_init, 'desired_dr_mode' is not yet correctly set based on enabled drivers and dr_mode in DT. - Added phy power on/off. - Added setting dma and coherent mask to 32-bits, because controller can do only 32-bit access. - Added Idle state for Type-C for TI platform as suggested by Roger. - Improved the flow according with Figure 24 from Software OTG Control user guide as sugested by Roger. Changes since v5: - Fixed controller issue with handling SETUP that has occurred on 0x0002450C controller version. In some case EP_STS_SETUP is reported but SETUP packet has not been copied yet to system memory. This bug caused that driver started handling the previous SETUP packet. - Added handling ZLP for EP0. - Removed unused cdns3_gadget_ep0_giveback function. - Fixed issue with disabling endpoint. Added waiting for clearing EP_STS_DBUSY bit between disabling endpoint and calling EP_CMD_EPRST command. EP_CMD_EPRST command can be called only when DMA is stopped. - Fixed issue: EP_CFG_TDL_CHK is currently supported only for OUT direction, It was enabled for both IN/OUT direction. - Improved resetting of interrupt in cdns3_device_irq_handler. - Fixed issue with ISOC IN transfer in cdns3_ep_run_transfer function. In some cases driver set incorrect Cycle Bit in TRBs. - Fixed issue in function
Re: [PATCH] /dev/mem: Bail out upon SIGKILL when reading memory.
* Tetsuo Handa wrote: > On 2019/08/26 1:54, Linus Torvalds wrote: > > On Sat, Aug 24, 2019 at 10:50 PM Tetsuo Handa > > wrote: > >> > >> @@ -142,7 +144,7 @@ static ssize_t read_mem(struct file *file, char __user > >> *buf, > >> sz = size_inside_page(p, count); > >> cond_resched(); > >> err = -EINTR; > >> - if (fatal_signal_pending(current)) > >> + if (signal_pending(current)) > >> goto failed; > >> > >> err = -EPERM; > > > > So from a "likelihood of breaking" standpoint, I'd really like to make > > sure that the "signal_pending()" checks come at the *end* of the loop. > > > > That way, if somebody is doing a 4-byte read from MMIO, he'll never see > > -EINTR. > > > > I'm specifically thinking of tools like user-space 'lspci' etc, which > > I wouldn't be surprised could happen. > > > > Also, just in case things break, I do agree with Ingo that this should > > be split up into several patches. > > Thinking from how read_mem() returns error code instead of returning bytes > already processed, any sane users will not try to read so much memory (like > 2GB). > If userspace programs want to read so much memory, there must have been > attempts > to improve performance. I guess that userspace program somehow knows which > region > to read and tries to read only meaningful pages (which would not become > hundreds MB). > Thus, I don't think we want to make /dev/{mem,kmem} intrruptible. Just making > killable > in case insane userspace program (like fuzzer) tried to read/write so much > memory > will be sufficient... Basically making IO primitives interruptible is the norm and it's a quality of implementation issue: it's only a historic accident that /dev/mem read()s aren't. So let's try and make it interruptible as the #3 patch I sent did - of course if anything breaks we'll have to undo it. But if we can get away with then by all means let's do so - even shorter reads can generate nasty long processing latencies. Ok? Thanks, Ingo
Re: linux-next: manual merge of the pinctrl tree with the gpio tree
On Mon, Aug 26, 2019 at 1:03 PM Stephen Rothwell wrote: > Today's linux-next merge of the pinctrl tree got a conflict in: > > drivers/pinctrl/bcm/pinctrl-bcm2835.c > > between commit: > > 82357f82ec69 ("pinctrl: bcm2835: Pass irqchip when adding gpiochip") > > from the gpio tree and commit: > > e38a9a437fb9 ("pinctrl: bcm2835: Add support for BCM2711 pull-up > functionality") > > from the pinctrl tree. Ah that's so unnecessary. I will take the patch out of the GPIO tree and put it into the pinctrl tree instead, thanks for noticing! Yours, Linus Walleij
[PATCH v2 1/2] mm, sl[ou]b: improve memory accounting
SLOB currently doesn't account its pages at all, so in /proc/meminfo the Slab field shows zero. Modifying a counter on page allocation and freeing should be acceptable even for the small system scenarios SLOB is intended for. Since reclaimable caches are not separated in SLOB, account everything as unreclaimable. SLUB currently doesn't account kmalloc() and kmalloc_node() allocations larger than order-1 page, that are passed directly to the page allocator. As they also don't appear in /proc/slabinfo, it might look like a memory leak. For consistency, account them as well. (SLAB doesn't actually use page allocator directly, so no change there). Ideally SLOB and SLUB would be handled in separate patches, but due to the shared kmalloc_order() function and different kfree() implementations, it's easier to patch both at once to prevent inconsistencies. Signed-off-by: Vlastimil Babka --- mm/slab_common.c | 8 ++-- mm/slob.c| 20 mm/slub.c| 14 +++--- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/mm/slab_common.c b/mm/slab_common.c index 807490fe217a..929c02a90fba 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1250,12 +1250,16 @@ void __init create_kmalloc_caches(slab_flags_t flags) */ void *kmalloc_order(size_t size, gfp_t flags, unsigned int order) { - void *ret; + void *ret = NULL; struct page *page; flags |= __GFP_COMP; page = alloc_pages(flags, order); - ret = page ? page_address(page) : NULL; + if (likely(page)) { + ret = page_address(page); + mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE, + 1 << order); + } ret = kasan_kmalloc_large(ret, size, flags); /* As ret might get tagged, call kmemleak hook after KASAN. */ kmemleak_alloc(ret, size, 1, flags); diff --git a/mm/slob.c b/mm/slob.c index 7f421d0ca9ab..3dcde9cf2b17 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -190,7 +190,7 @@ static int slob_last(slob_t *s) static void *slob_new_pages(gfp_t gfp, int order, int node) { - void *page; + struct page *page; #ifdef CONFIG_NUMA if (node != NUMA_NO_NODE) @@ -202,14 +202,21 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) if (!page) return NULL; + mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE, + 1 << order); return page_address(page); } static void slob_free_pages(void *b, int order) { + struct page *sp = virt_to_page(b); + if (current->reclaim_state) current->reclaim_state->reclaimed_slab += 1 << order; - free_pages((unsigned long)b, order); + + mod_node_page_state(page_pgdat(sp), NR_SLAB_UNRECLAIMABLE, + -(1 << order)); + __free_pages(sp, order); } /* @@ -521,8 +528,13 @@ void kfree(const void *block) int align = max_t(size_t, ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); unsigned int *m = (unsigned int *)(block - align); slob_free(m, *m + align); - } else - __free_pages(sp, compound_order(sp)); + } else { + unsigned int order = compound_order(sp); + mod_node_page_state(page_pgdat(sp), NR_SLAB_UNRECLAIMABLE, + -(1 << order)); + __free_pages(sp, order); + + } } EXPORT_SYMBOL(kfree); diff --git a/mm/slub.c b/mm/slub.c index 8834563cdb4b..74365d083a1e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3819,11 +3819,15 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node) { struct page *page; void *ptr = NULL; + unsigned int order = get_order(size); flags |= __GFP_COMP; - page = alloc_pages_node(node, flags, get_order(size)); - if (page) + page = alloc_pages_node(node, flags, order); + if (page) { ptr = page_address(page); + mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE, + 1 << order); + } return kmalloc_large_node_hook(ptr, size, flags); } @@ -3949,9 +3953,13 @@ void kfree(const void *x) page = virt_to_head_page(x); if (unlikely(!PageSlab(page))) { + unsigned int order = compound_order(page); + BUG_ON(!PageCompound(page)); kfree_hook(object); - __free_pages(page, compound_order(page)); + mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE, + -(1 << order)); + __free_pages(page, order); return; } slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_); -- 2.22.1
[PATCH v2 2/2] mm, sl[aou]b: guarantee natural alignment for kmalloc(power-of-two)
In most configurations, kmalloc() happens to return naturally aligned (i.e. aligned to the block size itself) blocks for power of two sizes. That means some kmalloc() users might unknowingly rely on that alignment, until stuff breaks when the kernel is built with e.g. CONFIG_SLUB_DEBUG or CONFIG_SLOB, and blocks stop being aligned. Then developers have to devise workaround such as own kmem caches with specified alignment [1], which is not always practical, as recently evidenced in [2]. The topic has been discussed at LSF/MM 2019 [3]. Adding a 'kmalloc_aligned()' variant would not help with code unknowingly relying on the implicit alignment. For slab implementations it would either require creating more kmalloc caches, or allocate a larger size and only give back part of it. That would be wasteful, especially with a generic alignment parameter (in contrast with a fixed alignment to size). Ideally we should provide to mm users what they need without difficult workarounds or own reimplementations, so let's make the kmalloc() alignment to size explicitly guaranteed for power-of-two sizes under all configurations. What this means for the three available allocators? * SLAB object layout happens to be mostly unchanged by the patch. The implicitly provided alignment could be compromised with CONFIG_DEBUG_SLAB due to redzoning, however SLAB disables redzoning for caches with alignment larger than unsigned long long. Practically on at least x86 this includes kmalloc caches as they use cache line alignment, which is larger than that. Still, this patch ensures alignment on all arches and cache sizes. * SLUB layout is also unchanged unless redzoning is enabled through CONFIG_SLUB_DEBUG and boot parameter for the particular kmalloc cache. With this patch, explicit alignment is guaranteed with redzoning as well. This will result in more memory being wasted, but that should be acceptable in a debugging scenario. * SLOB has no implicit alignment so this patch adds it explicitly for kmalloc(). The potential downside is increased fragmentation. While pathological allocation scenarios are certainly possible, in my testing, after booting a x86_64 kernel+userspace with virtme, around 16MB memory was consumed by slab pages both before and after the patch, with difference in the noise. [1] https://lore.kernel.org/linux-btrfs/c3157c8e8e0e7588312b40c853f65c02fe6c957a.1566399731.git.christophe.le...@c-s.fr/ [2] https://lore.kernel.org/linux-fsdevel/20190225040904.5557-1-ming@redhat.com/ [3] https://lwn.net/Articles/787740/ Signed-off-by: Vlastimil Babka --- Documentation/core-api/memory-allocation.rst | 4 ++ include/linux/slab.h | 4 ++ mm/slab_common.c | 11 - mm/slob.c| 42 +++- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/Documentation/core-api/memory-allocation.rst b/Documentation/core-api/memory-allocation.rst index 7744aa3bf2e0..27c54854b508 100644 --- a/Documentation/core-api/memory-allocation.rst +++ b/Documentation/core-api/memory-allocation.rst @@ -98,6 +98,10 @@ limited. The actual limit depends on the hardware and the kernel configuration, but it is a good practice to use `kmalloc` for objects smaller than page size. +The address of a chunk allocated with `kmalloc` is aligned to at least +ARCH_KMALLOC_MINALIGN bytes. For sizes of power of two bytes, the +alignment is also guaranteed to be at least to the respective size. + For large allocations you can use :c:func:`vmalloc` and :c:func:`vzalloc`, or directly request pages from the page allocator. The memory allocated by `vmalloc` and related functions is diff --git a/include/linux/slab.h b/include/linux/slab.h index 56c9c7eed34e..0d4c26395785 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -493,6 +493,10 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags) * kmalloc is the normal method of allocating memory * for objects smaller than page size in the kernel. * + * The allocated object address is aligned to at least ARCH_KMALLOC_MINALIGN + * bytes. For @size of power of two bytes, the alignment is also guaranteed + * to be at least to the size. + * * The @flags argument may be one of the GFP flags defined at * include/linux/gfp.h and described at * :ref:`Documentation/core-api/mm-api.rst ` diff --git a/mm/slab_common.c b/mm/slab_common.c index 929c02a90fba..b9ba93ad5c7f 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -993,10 +993,19 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name, unsigned int useroffset, unsigned int usersize) { int err; + unsigned int align = ARCH_KMALLOC_MINALIGN; s->name = name; s->size = s->object_size = size; - s->align = calculate_alignment(flags, ARCH_KMALLOC_MINALIGN, size); + + /* +* For power of two sizes, guarantee
Re: [PATCH] MAINTAINERS: change list for KVM/s390
On 09.08.19 09:19, Paolo Bonzini wrote: > KVM/s390 does not have a list of its own, and linux-s390 is in the > loop anyway thanks to the generic arch/s390 match. So use the generic > KVM list for s390 patches. > > Signed-off-by: Paolo Bonzini I see its already in next, but consider this acked. > --- > MAINTAINERS | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 1aec93695040..6498ebaca2f6 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -8788,7 +8788,7 @@ M: Christian Borntraeger > M: Janosch Frank > R: David Hildenbrand > R: Cornelia Huck > -L: linux-s...@vger.kernel.org > +L: k...@vger.kernel.org > W: http://www.ibm.com/developerworks/linux/linux390/ > T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git > S: Supported >
Re: poisoned pages do not play well in the buddy allocator
On Mon 26-08-19 12:41:50, Oscar Salvador wrote: [...] > I checked [1], and it seems that [2] was going towards fixing this kind of > issue. > > I think it is about time to revamp the whole thing. I completely agree. The current state of hwpoison is just too fragile to be practically usable. We keep getting bug reports (as pointed out by Oscar) when people try to test this via soft offlining. > @Naoya: I could give it a try if you are busy. That would be more than appreciated. I feel guilty to have it slip between cracks but I simply couldn't have found enough time to give it a serious look. Sorry about that. > [1] > https://lore.kernel.org/linux-mm/1541746035-13408-1-git-send-email-n-horigu...@ah.jp.nec.com/ > [2] > https://lore.kernel.org/linux-mm/1541746035-13408-9-git-send-email-n-horigu...@ah.jp.nec.com/ -- Michal Hocko SUSE Labs
Re: linux-next: build warning after merge of the staging tree
On Mon, Aug 26, 2019 at 05:53:28PM +0800, Gao Xiang wrote: [] > The attempt above compiles successfully as well... And I have tried > the following commands (Just in case...) and the result turns out > without any difference... > > $ make ARCH=x86_64 allmodconfig > $ make ARCH=x86_64 -j16 > > and I'm so confused now... Hope to get your hints... I think I got the warning now... Sorry, I thought it is a compile error. I am looking into that, sorry about that... Thanks, Gao Xiang > > Thanks, > Gao Xiang > > > > > Out of curiosity, are there some merge conflicts raised? Or could you give > > me some hints (code and .config) to reproduce that? since I don't find any > > potential issue in include/trace/events/erofs.h and fs/erofs/*... I have no > > idea what happened and how to do next... Thank you very much! > > > > Thanks, > > Gao Xiang > > > > > > > > Thanks, > > > Gao Xiang > > > > > > > > > > > > > > > Introduced by commit > > > > > > > > > > > > 47e4937a4a7c ("erofs: move erofs out of staging") > > > > > > > > > > > > (or, at least, exposed by it). It needs, at least, a "struct > > > > > > dentry;" > > > > > > added to the file. > > > > > > > > > > Odd, why has this never been seen before when the same files were in > > > > > drivers/staging/ and why 0-day isn't reporting this? > > > > > > > > I Think it is weird since it is never failed in staging and kbuild-all > > > > 0-day ci > > > > (my tree and you tree) > > > > > > > > > > > > > > Gao, can you send me a patch for this? > > > > > > > > Got it, I will look into that... > > > > > > > > Thanks, > > > > Gao Xiang > > > > > > > > > > > > > > thanks, > > > > > > >
[PATCH] powerpc/prom: convert PROM_BUG() to standard trap
Prior to commit 1bd98d7fbaf5 ("ppc64: Update BUG handling based on ppc32"), BUG() family was using BUG_ILLEGAL_INSTRUCTION which was an invalid instruction opcode to trap into program check exception. That commit converted them to using standard trap instructions, but prom/prom_init and their PROM_BUG() macro were left over. head_64.S and exception-64s.S were left aside as well. Convert them to using the standard BUG infrastructure. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/bug.h | 8 arch/powerpc/kernel/exceptions-64s.S | 3 ++- arch/powerpc/kernel/head_64.S| 6 -- arch/powerpc/kernel/prom_init.c | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index fed7e6241349..f47e6ff6554d 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -5,14 +5,6 @@ #include -/* - * Define an illegal instr to trap on the bug. - * We don't use 0 because that marks the end of a function - * in the ELF ABI. That's "Boo Boo" in case you wonder... - */ -#define BUG_OPCODE .long 0x00b00b00 /* For asm */ -#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */ - #ifdef CONFIG_BUG #ifdef __ASSEMBLY__ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6ba3cc2ef8ab..dded4672579d 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1467,7 +1467,8 @@ EXC_COMMON_BEGIN(fp_unavailable_common) RECONCILE_IRQ_STATE(r10, r11) addir3,r1,STACK_FRAME_OVERHEAD bl kernel_fp_unavailable_exception - BUG_OPCODE +0: trap + EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0 1: #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 91d297e696dd..9a0dd79a2480 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -182,7 +182,8 @@ __secondary_hold: isync bctr #else - BUG_OPCODE +0: trap + EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0 #endif CLOSE_FIXED_SECTION(first_256B) @@ -998,7 +999,8 @@ start_here_common: bl start_kernel /* Not reached */ - BUG_OPCODE + trap + EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0 /* * We put a few things here that have to be page-aligned. diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 514707ef6779..f2b63b4e1943 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -94,7 +94,7 @@ static int of_workarounds __prombss; #define PROM_BUG() do {\ prom_printf("kernel BUG at %s line 0x%x!\n", \ __FILE__, __LINE__);\ -__asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ + __builtin_trap(); \ } while (0) #ifdef DEBUG_PROM -- 2.13.3
Re: [PATCH] KVM: selftests: Detect max PA width from cpuid
On Mon, Aug 26, 2019 at 03:57:28PM +0800, Peter Xu wrote: > The dirty_log_test is failing on some old machines like Xeon E3-1220 > with tripple faults when writting to the tracked memory region: > > Test iterations: 32, interval: 10 (ms) > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > guest physical test memory offset: 0x7fbffef000 > Test Assertion Failure > dirty_log_test.c:138: false > pid=6137 tid=6139 - Success > 1 0x00401ca1: vcpu_worker at dirty_log_test.c:138 > 2 0x7f3dd9e392dd: ?? ??:0 > 3 0x7f3dd9b6a132: ?? ??:0 > Invalid guest sync status: exit_reason=SHUTDOWN > > It's because previously we moved the testing memory region from a > static place (1G) to the top of the system's physical address space, > meanwhile we stick to 39 bits PA for all the x86_64 machines. That's > not true for machines like Xeon E3-1220 where it only supports 36. > > Let's unbreak this test by dynamically detect PA width from CPUID > 0x8008. Meanwhile, even allow kvm_get_supported_cpuid_index() to > fail. I don't know whether that could be useful because I think > 0x8008 should be there for all x86_64 hosts, but I also think it's > not really helpful to assert in the kvm_get_supported_cpuid_index(). > > Fixes: b442324b581556e > CC: Paolo Bonzini > CC: Andrew Jones > CC: Radim Krčmář > CC: Thomas Huth > Signed-off-by: Peter Xu > --- > tools/testing/selftests/kvm/dirty_log_test.c | 22 +-- > .../selftests/kvm/lib/x86_64/processor.c | 3 --- > 2 files changed, 15 insertions(+), 10 deletions(-) > > diff --git a/tools/testing/selftests/kvm/dirty_log_test.c > b/tools/testing/selftests/kvm/dirty_log_test.c > index ceb52b952637..111592f3a1d7 100644 > --- a/tools/testing/selftests/kvm/dirty_log_test.c > +++ b/tools/testing/selftests/kvm/dirty_log_test.c > @@ -274,18 +274,26 @@ static void run_test(enum vm_guest_mode mode, unsigned > long iterations, > DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode)); > > #ifdef __x86_64__ > - /* > - * FIXME > - * The x86_64 kvm selftests framework currently only supports a > - * single PML4 which restricts the number of physical address > - * bits we can change to 39. > - */ > - guest_pa_bits = 39; > + { > + struct kvm_cpuid_entry2 *entry; > + > + entry = kvm_get_supported_cpuid_entry(0x8008); > + /* > + * Supported PA width can be smaller than 52 even if > + * we're with VM_MODE_P52V48_4K mode. Fetch it from It seems like x86_64 should create modes that actually work, rather than always using one named 'P52', but then needing to probe for the actual number of supported physical bits. Indeed testing all x86_64 supported modes, like aarch64 does, would even make more sense in this test. > + * the host to update the default value (SDM 4.1.4). > + */ > + if (entry) > + guest_pa_bits = entry->eax & 0xff; Are we sure > 39 bits will work with this test framework? I can't recall what led me to the FIXME above, other than things not working. It seems I was convinced we couldn't have more bits due to how pml4's were allocated, but maybe I misinterpreted it. > + else > + guest_pa_bits = 32; > + } > #endif > #ifdef __aarch64__ > if (guest_pa_bits != 40) > type = KVM_VM_TYPE_ARM_IPA_SIZE(guest_pa_bits); > #endif > + printf("Supported guest physical address width: %d\n", guest_pa_bits); > max_gfn = (1ul << (guest_pa_bits - guest_page_shift)) - 1; > guest_page_size = (1ul << guest_page_shift); > /* > diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c > b/tools/testing/selftests/kvm/lib/x86_64/processor.c > index 6cb34a0fa200..9de2fd310ac8 100644 > --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c > +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c > @@ -760,9 +760,6 @@ kvm_get_supported_cpuid_index(uint32_t function, uint32_t > index) > break; > } > } > - > - TEST_ASSERT(entry, "Guest CPUID entry not found: (EAX=%x, ECX=%x).", > - function, index); > return entry; > } > > -- > 2.21.0 > Thanks, drew
Re: [PATCH v6 08/57] MIPS: Remove dev_err() usage after platform_get_irq()
Hello, Stephen Boyd wrote: > We don't need dev_err() messages when platform_get_irq() fails now that > platform_get_irq() prints an error message itself when something goes > wrong. Let's remove these prints with a simple semantic patch. > > // > @@ > expression ret; > struct platform_device *E; > @@ > > ret = > ( > platform_get_irq(E, ...) > | > platform_get_irq_byname(E, ...) > ); > > if ( \( ret < 0 \| ret <= 0 \) ) > { > ( > -if (ret != -EPROBE_DEFER) > -{ ... > -dev_err(...); > -... } > | > ... > -dev_err(...); > ) > ... > } > // > > While we're here, remove braces on if statements that only have one > statement (manually). Applied to mips-next. > commit 322e577b02ab > https://git.kernel.org/mips/c/322e577b02ab > > Signed-off-by: Stephen Boyd > Signed-off-by: Paul Burton Thanks, Paul [ This message was auto-generated; if you believe anything is incorrect then please email paul.bur...@mips.com to report it. ]
Re: Linux-next-20190823: x86_64/i386: prot_hsymlinks.c:325: Failed to run cmd: useradd hsym
- Original Message - > Hi! > > Do you see this LTP prot_hsymlinks failure on linux next 20190823 on > > x86_64 and i386 devices? > > > > test output log, > > useradd: failure while writing changes to /etc/passwd > > useradd: /home/hsym was created, but could not be removed > > This looks like an unrelated problem, failure to write to /etc/passwd > probably means that filesystem is full or some problem happend and how > is remounted RO. In Naresh' example, root is on NFS: root=/dev/nfs rw nfsroot=10.66.16.123:/var/lib/lava/dispatcher/tmp/886412/extract-nfsrootfs-tyuevoxm,tcp,hard,intr 10.66.16.123:/var/lib/lava/dispatcher/tmp/886412/extract-nfsrootfs-tyuevoxm on / type nfs (rw,relatime,vers=2,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.66.16.123,mountvers=1,mountproto=tcp,local_lock=all,addr=10.66.16.123) devtmpfs on /dev type devtmpfs (rw,relatime,size=3977640k,nr_inodes=994410,mode=755) Following message repeats couple times in logs: NFS: Server wrote zero bytes, expected XXX Naresh, can you check if there are any errors on NFS server side? Maybe run NFS cthon against that server with client running next-20190822 and next-20190823. > > I do not see the kernel messages from this job anywhere at the job > pages, is it stored somewhere? It appears to be mixed in same log file: https://qa-reports.linaro.org/lkft/linux-next-oe/build/next-20190823/testrun/886412/log
Re: [PATCH v2 1/2] firmware: bcm47xx_nvram: Correct size_t printf format
Hello, Florian Fainelli wrote: > When building on a 64-bit host, we will get warnings like those: > > drivers/firmware/broadcom/bcm47xx_nvram.c:103:3: note: in expansion of macro > 'pr_err' >pr_err("nvram on flash (%i bytes) is bigger than the reserved space in > memory, will just copy the first %i bytes\n", >^~ > drivers/firmware/broadcom/bcm47xx_nvram.c:103:28: note: format string is > defined here >pr_err("nvram on flash (%i bytes) is bigger than the reserved space in > memory, will just copy the first %i bytes\n", >~^ >%li > > Use %zu instead for that purpose. Series applied to mips-next. > firmware: bcm47xx_nvram: Correct size_t printf format > commit feb4eb060c3a > https://git.kernel.org/mips/c/feb4eb060c3a > > Signed-off-by: Florian Fainelli > Reviewed-by: Philippe Mathieu-Daudé > Signed-off-by: Paul Burton > > firmware: bcm47xx_nvram: Allow COMPILE_TEST > commit 5699ad0aaf10 > https://git.kernel.org/mips/c/5699ad0aaf10 > > Signed-off-by: Florian Fainelli > Signed-off-by: Paul Burton Thanks, Paul [ This message was auto-generated; if you believe anything is incorrect then please email paul.bur...@mips.com to report it. ]
linux-next: manual merge of the pinctrl tree with the gpio tree
Hi all, Today's linux-next merge of the pinctrl tree got a conflict in: drivers/pinctrl/bcm/pinctrl-bcm2835.c between commit: 82357f82ec69 ("pinctrl: bcm2835: Pass irqchip when adding gpiochip") from the gpio tree and commit: e38a9a437fb9 ("pinctrl: bcm2835: Add support for BCM2711 pull-up functionality") from the pinctrl tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc drivers/pinctrl/bcm/pinctrl-bcm2835.c index b729997cd887,a493205bedaf.. --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@@ -994,9 -1087,10 +1086,11 @@@ static int bcm2835_pinctrl_probe(struc struct device *dev = >dev; struct device_node *np = dev->of_node; struct bcm2835_pinctrl *pc; + struct gpio_irq_chip *girq; struct resource iomem; int err, i; + const struct of_device_id *match; + BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS); BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS); @@@ -1069,6 -1141,38 +1163,12 @@@ return err; } - err = gpiochip_irqchip_add(>gpio_chip, _gpio_irq_chip, - 0, handle_level_irq, IRQ_TYPE_NONE); - if (err) { - dev_info(dev, "could not add irqchip\n"); - return err; - } - - for (i = 0; i < BCM2835_NUM_IRQS; i++) { - pc->irq[i] = irq_of_parse_and_map(np, i); - - if (pc->irq[i] == 0) - continue; - - /* - * Use the same handler for all groups: this is necessary - * since we use one gpiochip to cover all lines - the - * irq handler then needs to figure out which group and - * bank that was firing the IRQ and look up the per-group - * and bank data. - */ - gpiochip_set_chained_irqchip(>gpio_chip, - _gpio_irq_chip, - pc->irq[i], - bcm2835_gpio_irq_handler); - } - + match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node); + if (match) { + bcm2835_pinctrl_desc.confops = + (const struct pinconf_ops *)match->data; + } + pc->pctl_dev = devm_pinctrl_register(dev, _pinctrl_desc, pc); if (IS_ERR(pc->pctl_dev)) { gpiochip_remove(>gpio_chip); pgptrmUzRNXmh.pgp Description: OpenPGP digital signature
Re: WARNINGs in set_task_reclaim_state with memory cgroup and full memory usage
On Fri 23-08-19 18:03:01, Yang Shi wrote: > > > On 8/23/19 3:00 PM, Adric Blake wrote: > > Synopsis: > > A WARN_ON_ONCE is hit twice in set_task_reclaim_state under the > > following conditions: > > - a memory cgroup has been created and a task assigned it it > > - memory.limit_in_bytes has been set > > - memory has filled up, likely from cache > > > > In my usage, I create a cgroup under the current session scope and > > assign a task to it. I then set memory.limit_in_bytes and > > memory.soft_limit_in_bytes for the cgroup to reasonable values, say > > 1G/512M. The program accesses large files frequently and gradually > > fills memory with the page cache. The warnings appears when the > > entirety of the system memory is filled, presumably from other > > programs. > > > > If I wait until the program has filled the entirety of system memory > > with cache and then assign a memory limit, the warnings appear > > immediately. > > It looks the warning is triggered because kswapd set reclaim_state then the > memcg soft limit reclaim in the same kswapd set it again. Yes, this is indeed the case. The same seems possible from the direct reclaim AFAICS. > But, kswapd and memcg soft limit uses different reclaim_state from different > scan control. It sounds not correct, they should use the same reclaim_state > if they come from the same context if my understanding is correct. I haven't checked very closely and I might be wrong but setting the reclaim state from the mem_cgroup_shrink_node doesn't make any sense in the current code. The soft limit is always called from the global reclaim and both kswapd and the direct reclaim already track reclaim state correctly. We just haven't noticed until now beause the warning is quite recent and mostly likely only few people tend to use soft limit these days. That being said, we should simply do this instead: >From 59d128214a62bf2d83c2a2a9cde887b4817275e7 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Mon, 26 Aug 2019 12:43:15 +0200 Subject: [PATCH] mm, memcg: do not set reclaim_state on soft limit reclaim Adric Blake has noticed the following warning: [38491.963105] WARNING: CPU: 7 PID: 175 at mm/vmscan.c:245 set_task_reclaim_state+0x1e/0x40 [...] [38491.963239] Call Trace: [38491.963246] mem_cgroup_shrink_node+0x9b/0x1d0 [38491.963250] mem_cgroup_soft_limit_reclaim+0x10c/0x3a0 [38491.963254] balance_pgdat+0x276/0x540 [38491.963258] kswapd+0x200/0x3f0 [38491.963261] ? wait_woken+0x80/0x80 [38491.963265] kthread+0xfd/0x130 [38491.963267] ? balance_pgdat+0x540/0x540 [38491.963269] ? kthread_park+0x80/0x80 [38491.963273] ret_from_fork+0x35/0x40 [38491.963276] ---[ end trace 727343df67b2398a ]--- which tells us that soft limit reclaim is about to overwrite the reclaim_state configured up in the call chain (kswapd in this case but the direct reclaim is equally possible). This means that reclaim stats would get misleading once the soft reclaim returns and another reclaim is done. Fix the warning by dropping set_task_reclaim_state from the soft reclaim which is always called with reclaim_state set up. Reported-by: Adric Blake Signed-off-by: Michal Hocko --- mm/vmscan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index c77d1e3761a7..a6c5d0b28321 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -3220,6 +3220,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, #ifdef CONFIG_MEMCG +/* Only used by soft limit reclaim. Do not reuse for anything else. */ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, gfp_t gfp_mask, bool noswap, pg_data_t *pgdat, @@ -3235,7 +3236,8 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, }; unsigned long lru_pages; - set_task_reclaim_state(current, _state); + WARN_ON_ONCE(!current->reclaim_state); + sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); @@ -3253,7 +3255,6 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed); - set_task_reclaim_state(current, NULL); *nr_scanned = sc.nr_scanned; return sc.nr_reclaimed; -- 2.20.1 -- Michal Hocko SUSE Labs
Re: [PATCH] KVM: selftests: Detect max PA width from cpuid
On Mon, Aug 26, 2019 at 10:25:55AM +0200, Vitaly Kuznetsov wrote: > Peter Xu writes: > > > The dirty_log_test is failing on some old machines like Xeon E3-1220 > > with tripple faults when writting to the tracked memory region: > > s,writting,writing, > > > > > Test iterations: 32, interval: 10 (ms) > > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > > guest physical test memory offset: 0x7fbffef000 > > Test Assertion Failure > > dirty_log_test.c:138: false > > pid=6137 tid=6139 - Success > > 1 0x00401ca1: vcpu_worker at dirty_log_test.c:138 > > 2 0x7f3dd9e392dd: ?? ??:0 > > 3 0x7f3dd9b6a132: ?? ??:0 > > Invalid guest sync status: exit_reason=SHUTDOWN > > > > This patch breaks on my AMD machine with > > # cpuid -1 -l 0x8008 > CPU: >Physical Address and Linear Address Size (0x8008/eax): > maximum physical address bits = 0x30 (48) > maximum linear (virtual) address bits = 0x30 (48) > maximum guest physical address bits = 0x0 (0) > > > Pre-patch: > > # ./dirty_log_test > Test iterations: 32, interval: 10 (ms) > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > guest physical test memory offset: 0x7fbffef000 > Dirtied 139264 pages > Total bits checked: dirty (135251), clear (7991709), track_next (29789) > > Post-patch: > > # ./dirty_log_test > Test iterations: 32, interval: 10 (ms) > Testing guest mode: PA-bits:52, VA-bits:48, 4K pages > Supported guest physical address width: 48 > guest physical test memory offset: 0xbffef000 > Test Assertion Failure > dirty_log_test.c:141: false > pid=77983 tid=77985 - Success > 10x00401d12: vcpu_worker at dirty_log_test.c:138 > 20x7f636374358d: ?? ??:0 > 30x7f63636726a2: ?? ??:0 > Invalid guest sync status: exit_reason=SHUTDOWN Vitaly, Are you using shadow paging? If so, could you try NPT=off? I finally found a AMD host and I also found that it's passing with shadow MMU mode which is strange. If so I would suspect it's a real bug in AMD NTP path but I'd like to see whether it's also happening on your side. Thanks, -- Peter Xu
[PATCH v2 2/4] vesnin: add secondary SPI flash chip
Adds secondary SPI flash chip into dts for vesnin. Signed-off-by: Ivan Mikhaylov --- arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts index 2ee26c86a32e..db4cc3df61ce 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts @@ -81,6 +81,14 @@ label = "bmc"; #include "openbmc-flash-layout.dtsi" }; + + flash@1 { + status = "okay"; + reg = < 1 >; + compatible = "jedec,spi-nor"; + m25p,fast-read; + label = "alt"; + }; }; { -- 2.20.1
[PATCH v2 0/4] add dual-boot support
ASPEED SoCs support dual-boot feature for SPI Flash. When strapped appropriately, the SoC starts wdt2 (/dev/watchdog1) and if within a minute it is not disabled, it goes off and reboots the SoC from an alternate SPI Flash chip by changing CS0 controls to actually drive CS1 line. When booted from alternate chip, in order to access the main chip at CS0, the user must reset the appropriate bit in the watchdog hardware. There is no interface that would allow to do that from an embedded firmware startup script. This commit implements support for that feature: * Enable 'alt-boot' option for wdt2 * Enable secondary SPI flash chip * Make it possible to get access to the primary SPI flash chip at CS0 after booting from the alternate chip at CS1. A sysfs interface is added to provide an easy way for embedded firmware startup scripts to clear the chip select bit to gain access to the primary flash chip in order to allow for recovery of its contents. Ivan Mikhaylov (4): vesnin: add wdt2 section with alt-boot option vesnin: add secondary SPI flash chip watchdog/aspeed: add support for dual boot dt-bindings/watchdog: Add access_cs0 option for alt-boot .../bindings/watchdog/aspeed-wdt.txt | 7 +++ arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 12 drivers/watchdog/aspeed_wdt.c | 62 ++- 3 files changed, 80 insertions(+), 1 deletion(-) -- 2.20.1
[PATCH v2 1/4] vesnin: add wdt2 section with alt-boot option
Adds wdt2 section with 'alt-boot' option into dts for vesnin. Signed-off-by: Ivan Mikhaylov --- arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 4 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts index 0b9e29c3212e..2ee26c86a32e 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts @@ -222,3 +222,7 @@ { status = "okay"; }; + + { + aspeed,alt-boot; +}; -- 2.20.1
[PATCH v2 3/4] watchdog/aspeed: add support for dual boot
Set WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION into WDT_CLEAR_TIMEOUT_STATUS to clear out boot code source and re-enable access to the primary SPI flash chip while booted via wdt2 from the alternate chip. AST2400 datasheet says: "In the 2nd flash booting mode, all the address mapping to CS0# would be re-directed to CS1#. And CS0# is not accessable under this mode. To access CS0#, firmware should clear the 2nd boot mode register in the WDT2 status register WDT30.bit[1]." Signed-off-by: Ivan Mikhaylov --- drivers/watchdog/aspeed_wdt.c | 62 ++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index cc71861e033a..bbc42847c0e3 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -53,6 +53,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); #define WDT_CTRL_ENABLE BIT(0) #define WDT_TIMEOUT_STATUS 0x10 #define WDT_TIMEOUT_STATUS_BOOT_SECONDARYBIT(1) +#define WDT_CLEAR_TIMEOUT_STATUS 0x14 +#define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTIONBIT(0) /* * WDT_RESET_WIDTH controls the characteristics of the external pulse (if @@ -165,6 +167,57 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd, return 0; } +/* access_cs0 shows if cs0 is accessible, hence the reverted bit */ +static ssize_t access_cs0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aspeed_wdt *wdt = dev_get_drvdata(dev); + uint32_t status = readl(wdt->base + WDT_TIMEOUT_STATUS); + + return sprintf(buf, "%u\n", + !(status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)); +} + +static ssize_t access_cs0_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct aspeed_wdt *wdt = dev_get_drvdata(dev); + unsigned long val; + + if (kstrtoul(buf, 10, )) + return -EINVAL; + + if (val) + writel(WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION, + wdt->base + WDT_CLEAR_TIMEOUT_STATUS); + + return size; +} + +/* + * At alternate side the 'access_cs0' sysfs node provides: + * ast2400: a way to get access to the primary SPI flash chip at CS0 + *after booting from the alternate chip at CS1. + * ast2500: a way to restore the normal address mapping from + *(CS0->CS1, CS1->CS0) to (CS0->CS0, CS1->CS1). + * + * Clearing the boot code selection and timeout counter also resets to the + * initial state the chip select line mapping. When the SoC is in normal + * mapping state (i.e. booted from CS0), clearing those bits does nothing for + * both versions of the SoC. For alternate boot mode (booted from CS1 due to + * wdt2 expiration) the behavior differs as described above. + * + * This option can be used with wdt2 (watchdog1) only. + */ +static DEVICE_ATTR_RW(access_cs0); + +static struct attribute *bswitch_attrs[] = { + _attr_access_cs0.attr, + NULL +}; +ATTRIBUTE_GROUPS(bswitch); + static const struct watchdog_ops aspeed_wdt_ops = { .start = aspeed_wdt_start, .stop = aspeed_wdt_stop, @@ -306,9 +359,16 @@ static int aspeed_wdt_probe(struct platform_device *pdev) } status = readl(wdt->base + WDT_TIMEOUT_STATUS); - if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) + if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) { wdt->wdd.bootstatus = WDIOF_CARDRESET; + if (of_device_is_compatible(np, "aspeed,ast2400-wdt") || + of_device_is_compatible(np, "aspeed,ast2500-wdt")) + wdt->wdd.groups = bswitch_groups; + } + + dev_set_drvdata(dev, wdt); + return devm_watchdog_register_device(dev, >wdd); } -- 2.20.1
[PATCH v2 4/4] dt-bindings/watchdog: Add access_cs0 option for alt-boot
The option for the ast2400/2500 to get access to CS0 at runtime. Signed-off-by: Ivan Mikhaylov --- Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt | 7 +++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt index c5077a1f5cb3..023a9b578df6 100644 --- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt @@ -34,6 +34,13 @@ Optional properties: engine is responsible for this. - aspeed,alt-boot:If property is present then boot from alternate block. + At alternate side 'access_cs0' sysfs file provides: + ast2400: a way to get access to the primary SPI flash +chip at CS0 after booting from the alternate +chip at CS1. + ast2500: a way to restore the normal address mapping from +(CS0->CS1, CS1->CS0) to (CS0->CS0, CS1->CS1). + - aspeed,external-signal: If property is present then signal is sent to external reset counter (only WDT1 and WDT2). If not specified no external signal is sent. -- 2.20.1
poisoned pages do not play well in the buddy allocator
Hi, When analyzing a problem reported by one of our customers, I stumbbled upon an issue that origins from the fact that poisoned pages end up in the buddy allocator. Let me break down the stepts that lie to the problem: 1) We soft-offline a page 2) Page gets flagged as HWPoison and is being sent to the buddy allocator. This is done through set_hwpoison_free_buddy_page(). 3) Kcompactd wakes up in order to perform some compaction. 4) compact_zone() will call migrate_pages() 5) migrate_pages() will try to get a new page from compaction_alloc() to migrate to 6) if cc->freelist is empty, compaction_alloc() will call isolate_free_pagesblock() 7) isolate_free_pagesblock only checks for PageBuddy() to assume that a page is OK to be used to migrate to. Since HWPoisoned page are also PageBuddy, we add the page to the list. (same problem exists in fast_isolate_freepages()). The outcome of that is that we end up happily handing poisoned pages in compaction_alloc, so if we ever got a fault on that page through *_fault, we will return VM_FAULT_HWPOISON, and the process will be killed. I first though that I could get away with it by checking PageHWPoison in {fast_isolate_freepages/isolate_free_pagesblock}, but not really. It might be that the page we are checking is an order > 0 page, so the first page might not be poisoned, but the one the follows might be, and we end up in the same situation. After some more thought, I really came to the conclusion that HWPoison pages should not really be in the buddy allocator, as this is only asking for problems. In this case it is only compaction code, but it could be happening somewhere else, and one would expect that the pages you got from the buddy allocator are __ready__ to use. I __think__ that we thought we were safe to put HWPoison pages in the buddy allocator as we perform healthy checks when getting a page from there, so we skip poisoned pages Of course, this is not the end of the story, now that someone got a page, if he frees it, there is a high chance that this page ends up in a pcplist (I saw that). Unless we are on CONFIG_VM_DEBUG, we do not check for the health of pages got from pcplist, as we do when getting a page from the buddy allocator. I checked [1], and it seems that [2] was going towards fixing this kind of issue. I think it is about time to revamp the whole thing. @Naoya: I could give it a try if you are busy. [1] https://lore.kernel.org/linux-mm/1541746035-13408-1-git-send-email-n-horigu...@ah.jp.nec.com/ [2] https://lore.kernel.org/linux-mm/1541746035-13408-9-git-send-email-n-horigu...@ah.jp.nec.com/ -- Oscar Salvador SUSE L3