[PATCH] Staging: Ralink: ralink-gdma: Fixed codestyle issue and warnings
Fixed checkpatch warnings two warnings still exits about DT compatible strings appers undocumented. Fixed the other codestyle errors, and some warnings about use of volatile and un-necessary out of memory errors. Signed-off-by: Naveen Panwar --- drivers/staging/ralink-gdma/ralink-gdma.c | 29 --- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/ralink-gdma/ralink-gdma.c b/drivers/staging/ralink-gdma/ralink-gdma.c index eabf10933..1c3388b7c 100644 --- a/drivers/staging/ralink-gdma/ralink-gdma.c +++ b/drivers/staging/ralink-gdma/ralink-gdma.c @@ -122,7 +122,8 @@ struct gdma_dma_dev { struct gdma_data *data; void __iomem *base; struct tasklet_struct task; - volatile unsigned long chan_issued; + + unsigned long chan_issued; atomic_t cnt; struct gdma_dmaengine_chan chan[]; @@ -135,8 +136,8 @@ struct gdma_data { int (*start_transfer)(struct gdma_dmaengine_chan *chan); }; -static struct gdma_dma_dev *gdma_dma_chan_get_dev( - struct gdma_dmaengine_chan *chan) +static struct gdma_dma_dev *gdma_dma_chan_get_dev + (struct gdma_dmaengine_chan *chan) { return container_of(chan->vchan.chan.device, struct gdma_dma_dev, ddev); @@ -510,10 +511,10 @@ static void gdma_dma_issue_pending(struct dma_chan *c) spin_unlock_irqrestore(&chan->vchan.lock, flags); } -static struct dma_async_tx_descriptor *gdma_dma_prep_slave_sg( - struct dma_chan *c, struct scatterlist *sgl, - unsigned int sg_len, enum dma_transfer_direction direction, - unsigned long flags, void *context) +static struct dma_async_tx_descriptor *gdma_dma_prep_slave_sg + (struct dma_chan *c, struct scatterlist *sgl, +unsigned int sg_len, enum dma_transfer_direction direction, +unsigned long flags, void *context) { struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c); struct gdma_dma_desc *desc; @@ -522,7 +523,7 @@ static struct dma_async_tx_descriptor *gdma_dma_prep_slave_sg( desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC); if (!desc) { - dev_err(c->device->dev, "alloc sg decs error\n"); + goto free_rx_tx; return NULL; } desc->residue = 0; @@ -558,9 +559,9 @@ static struct dma_async_tx_descriptor *gdma_dma_prep_slave_sg( return NULL; } -static struct dma_async_tx_descriptor *gdma_dma_prep_dma_memcpy( - struct dma_chan *c, dma_addr_t dest, dma_addr_t src, - size_t len, unsigned long flags) +static struct dma_async_tx_descriptor *gdma_dma_prep_dma_memcpy + (struct dma_chan *c, dma_addr_t dest, dma_addr_t src, +size_t len, unsigned long flags) { struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c); struct gdma_dma_desc *desc; @@ -577,7 +578,7 @@ static struct dma_async_tx_descriptor *gdma_dma_prep_dma_memcpy( desc = kzalloc(struct_size(desc, sg, num_periods), GFP_ATOMIC); if (!desc) { - dev_err(c->device->dev, "alloc memcpy decs error\n"); + goto free_rx_tx; return NULL; } desc->residue = len; @@ -601,8 +602,8 @@ static struct dma_async_tx_descriptor *gdma_dma_prep_dma_memcpy( return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); } -static struct dma_async_tx_descriptor *gdma_dma_prep_dma_cyclic( - struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len, +static struct dma_async_tx_descriptor *gdma_dma_prep_dma_cyclic + (struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len, size_t period_len, enum dma_transfer_direction direction, unsigned long flags) { -- 2.17.1
Re: [Linux-kernel-mentees] [PATCH v1 1/2] video: fbdev: aty: radeon_pm: remove redundant CONFIG_PM container
On Mon, Sep 07, 2020 at 08:48:10AM +0200, Greg KH wrote: > On Mon, Sep 07, 2020 at 12:03:47PM +0530, Vaibhav Gupta wrote: > > > > Why did you send empty emails out? > > greg k-h I was trying to re-ping the patches. Guess it went empty. I will send patches again. Vaibhav
Re: [PATCH] /dev/zero: also implement ->read
On 07/09/2020 08.20, Christoph Hellwig wrote: > On Mon, Sep 07, 2020 at 12:34:37AM +0200, Rasmus Villemoes wrote: >> On 03/09/2020 17.59, Christoph Hellwig wrote: > >>> +static ssize_t read_zero(struct file *file, char __user *buf, >>> +size_t count, loff_t *ppos) >>> +{ >>> + size_t cleared = 0; >>> + >>> + while (count) { >>> + size_t chunk = min_t(size_t, count, PAGE_SIZE); >>> + >>> + if (clear_user(buf + cleared, chunk)) >>> + return cleared ? cleared : -EFAULT; >> >> Probably nobody really cares, but currently doing >> >> read(fd, &unmapped_page - 5, 123); >> >> returns 5, and those five bytes do get cleared; if I'm reading the above >> right you'd return -EFAULT for that case. >> >> >>> + cleared += chunk; >>> + count -= chunk; >>> + >>> + if (signal_pending(current)) >>> + return cleared ? cleared : -ERESTARTSYS; >> >> I can't see how we can get here without 'cleared' being positive, so >> this can just be 'return cleared' (and if you fix the above EFAULT case >> to more accurately track how much got cleared, there's probably no >> longer any code to be symmetric with anyway). > > Yeah, I'll fix these up and resend. > Actually, while you're micro-optimizing it, AFAIK VFS already handles count==0, so you can avoid the initial branch and the last cond_resched() by writing it something like while (1) { size_t chunk = min_t(size_t, count, PAGE_SIZE), c; c = chunk - clear_user(buf + cleared, chunk); if (unlikely(!c)) return cleared ?: -EFAULT; cleared += c; count -= c; if (!count || signal_pending()) return cleared; cond_resched(); } For the dd test case with the default bs=512 that avoids cond_resched() and signal_pending() altogether. Rasmus
Re: [PATCH v7] binder: transaction latency tracking for user build
On Thu, 2020-09-03 at 18:21 +0200, Greg Kroah-Hartman wrote: > On Tue, Aug 04, 2020 at 09:59:09PM +0800, Frankie Chang wrote: > > > > Frankie.Chang (3): > > binder: move structs from core file to header file > > binder: add trace at free transaction. > > binder: add transaction latency tracer > > > > drivers/android/Kconfig |8 + > > drivers/android/Makefile|1 + > > drivers/android/binder.c| 425 > > ++- > > drivers/android/binder_internal.h | 417 > > ++ > > drivers/android/binder_latency_tracer.c | 112 > > drivers/android/binder_trace.h | 49 > > 6 files changed, 607 insertions(+), 405 deletions(-) create mode 100644 > > drivers/android/binder_latency_tracer.c > > This series blows up the build into lots of tiny pieces, how was it > tested? > I am sorry that I had built pass.on the too older kernel, and some of api had been deprecated. I have fixed these errors in local, and I add the EXPORT_TRACEPOINT_SYMBOL for binder_latency_tracer to be ko needed. Do I need to push a patch V8 or I provide the fixed code here ? ~/mtk_soc_new$ cat b.log | grep binder CC drivers/android/binderfs.o CC drivers/android/binder.o CC [M] drivers/android/binder_latency_tracer.o LD [M] drivers/android/binder_latency_tracer.ko ~/mtk_soc_new$ tail -n 10 b.log make[1]: Leaving directory `/proj/mtk16184/mtk_soc_new/kernel/mediatek' make ARCH=arm64 CROSS_COMPILE=/proj/mtk16184/mtk_soc_new/prebuilt/toolchain/aarch64/usr/bin/aarch64-poky-linux/aarch64-poky-linux- O=/proj/mtk16184/mtk_soc_new/out -C kernel/mediatek dtbs make[1]: Entering directory `/proj/mtk16184/mtk_soc_new/kernel/mediatek' make[2]: Entering directory `/proj/mtk16184/mtk_soc_new/out' arch/arm64/Makefile:26: ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum arch/arm64/Makefile:34: LSE atomics not supported by binutils make[2]: Leaving directory `/proj/mtk16184/mtk_soc_new/out' make[1]: Leaving directory `/proj/mtk16184/mtk_soc_new/kernel/mediatek' cat /proj/mtk16184/mtk_soc_new/out/arch/arm64/boot/Image.gz /proj/mtk16184/mtk_soc_new/out/arch/arm64/boot/dts/mediatek/mt6779-evb.dtb > /proj/mtk16184/mtk_soc_new/out/arch/arm64/boot/Image.gz-dtb /proj/mtk16184/mtk_soc_new/prebuilt/bootable/mkbootimg --kernel /proj/mtk16184/mtk_soc_new/out/arch/arm64/boot/Image.gz-dtb --ramdisk /proj/mtk16184/mtk_soc_new/prebuilt/bootable/6779_loader/ramdisk.img --base 0x4000 --ramdisk_offset 0x0400 --kernel_offset 0x0008 --cmdline bootopt=64S3,32N2,64N2 --output /proj/mtk16184/mtk_soc_new/prebuilt/bootable/6779_loader/boot.img > Here's my error logs: > > In file included from drivers/android/binderfs.c:37: > drivers/android/binder_internal.h:537:17: error: field ‘tv’ has incomplete > type > 537 | struct timeval tv; > | ^~ > In file included from drivers/android/binder_trace.h:12, > from drivers/android/binder_alloc.c:27: > drivers/android/binder_trace.h: In function ‘trace_binder_txn_latency_alloc’: > drivers/android/binder_trace.h:100:13: error: ‘e’ undeclared (first use in > this function) > 100 | TP_ARGS(t, e) > | ^ > ./include/linux/tracepoint.h:191:33: note: in definition of macro ‘__DO_TRACE’ > 191 | ((void(*)(proto))(it_func))(args); \ > | ^~~~ > ./include/linux/tracepoint.h:236:5: note: in expansion of macro ‘TP_ARGS’ > 236 | TP_ARGS(data_args), \ > | ^~~ > ./include/linux/tracepoint.h:375:2: note: in expansion of macro > ‘__DECLARE_TRACE’ > 375 | __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ > | ^~~ > ./include/linux/tracepoint.h:378:4: note: in expansion of macro ‘PARAMS’ > 378 |PARAMS(__data, args)) > |^~ > drivers/android/binder_trace.h:98:1: note: in expansion of macro > ‘DECLARE_TRACE’ >98 | DECLARE_TRACE(binder_txn_latency_alloc, > | ^ > drivers/android/binder_trace.h:100:2: note: in expansion of macro ‘TP_ARGS’ > 100 | TP_ARGS(t, e) > | ^~~ > drivers/android/binder_trace.h:100:13: note: each undeclared identifier is > reported only once for each function it appears in > 100 | TP_ARGS(t, e) > | ^ > ./include/linux/tracepoint.h:191:33: note: in definition of macro ‘__DO_TRACE’ > 191 | ((void(*)(proto))(it_func))(args); \ > | ^~~~ > ./include/linux/tracepoint.h:236:5: note: in expansion of macro ‘TP_ARGS’ > 236 | TP_ARGS(data_args), \ > | ^~~ > ./include/linux/tracepoint.h:375:2: note: in expansion of macro > ‘__DECLARE_TRACE’ > 375 | __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ > | ^~~ > ./include/linux/tracepoint.h:378:4: note: in expansion of macro ‘PARAMS’ > 378 |PARAMS(__data, args)) > |^~
Re: [PATCH v4 4/7] power: supply: max17040: Support compatible devices
Hi Iskren, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on b36c969764ab12faebb74711c942fa3e6eaf1e96] url: https://github.com/0day-ci/linux/commits/Iskren-Chernev/power-supply-max17040-support-compatible-devices/20200907-112145 base:b36c969764ab12faebb74711c942fa3e6eaf1e96 config: x86_64-randconfig-r026-20200907 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project ab68517e6b7e51b84c4b0e813a30258ec1ce5da5) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/power/supply/max17040_battery.c:410:13: warning: cast to smaller >> integer type 'enum chip_id' from 'const void *' [-Wvoid-pointer-to-enum-cast] chip_id = (enum chip_id) of_device_get_match_data(&client->dev); ^ 1 warning generated. # https://github.com/0day-ci/linux/commit/20c853834c05ddde6df590b46b94ef66477df1d0 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Iskren-Chernev/power-supply-max17040-support-compatible-devices/20200907-112145 git checkout 20c853834c05ddde6df590b46b94ef66477df1d0 vim +410 drivers/power/supply/max17040_battery.c 385 386 static int max17040_probe(struct i2c_client *client, 387 const struct i2c_device_id *id) 388 { 389 struct i2c_adapter *adapter = client->adapter; 390 struct power_supply_config psy_cfg = {}; 391 struct max17040_chip *chip; 392 enum chip_id chip_id; 393 int ret; 394 395 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) 396 return -EIO; 397 398 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 399 if (!chip) 400 return -ENOMEM; 401 402 chip->client = client; 403 chip->regmap = devm_regmap_init_i2c(client, &max17040_regmap); 404 chip->pdata = client->dev.platform_data; 405 chip_id = (enum chip_id) id->driver_data; 406 if (client->dev.of_node) { 407 ret = max17040_get_of_data(chip); 408 if (ret) 409 return ret; > 410 chip_id = (enum chip_id) > of_device_get_match_data(&client->dev); 411 } 412 chip->data = max17040_family[chip_id]; 413 414 i2c_set_clientdata(client, chip); 415 psy_cfg.drv_data = chip; 416 417 chip->battery = devm_power_supply_register(&client->dev, 418 &max17040_battery_desc, &psy_cfg); 419 if (IS_ERR(chip->battery)) { 420 dev_err(&client->dev, "failed: power supply register\n"); 421 return PTR_ERR(chip->battery); 422 } 423 424 ret = max17040_get_version(chip); 425 if (ret < 0) 426 return ret; 427 dev_dbg(&chip->client->dev, "MAX17040 Fuel-Gauge Ver 0x%x\n", ret); 428 429 if (chip_id == ID_MAX17040 || chip_id == ID_MAX17041) 430 max17040_reset(chip); 431 432 /* check interrupt */ 433 if (client->irq && chip->data.has_low_soc_alert) { 434 ret = max17040_set_low_soc_alert(chip, chip->low_soc_alert); 435 if (ret) { 436 dev_err(&client->dev, 437 "Failed to set low SOC alert: err %d\n", ret); 438 return ret; 439 } 440 441 ret = max17040_enable_alert_irq(chip); 442 if (ret) { 443 client->irq = 0; 444 dev_warn(&client->dev, 445 "Failed to get IRQ err %d\n", ret); 446 } 447 } 448 449 INIT_DEFERRABLE_WORK(&chip->work, max17040_work); 450 ret = devm_add_action(&client->dev, max17040_stop_work, chip); 451 if (ret) 452 return ret; 453 max17040_queue_work(chip); 454 455 return 0; 456 } 457 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: [Linux-kernel-mentees] [PATCH v1 1/2] video: fbdev: aty: radeon_pm: remove redundant CONFIG_PM container
On Mon, Sep 07, 2020 at 12:03:47PM +0530, Vaibhav Gupta wrote: > Why did you send empty emails out? greg k-h
Re: [PATCH 2/2] xfs: don't update mtime on COW faults
> +static bool > +xfs_is_write_fault( > + struct vm_fault *vmf) > +{ > + return vmf->flags & FAULT_FLAG_WRITE && vmf->vma->vm_flags & VM_SHARED; > +} This function does not look xfs specific at all. Why isn't it it in fs.h? While we're at it the name sounds rather generic, and there are no good comments. Maybe we just need to split FAULT_FLAG_WRITE into two and check those instead of such crazy workarounds?
Re: [Linux-kernel-mentees] [PATCH v1 0/2] video: fbdev: radeonfb: PCI PM framework upgrade and fix-ups.
On Mon, Sep 07, 2020 at 12:01:53PM +0530, Vaibhav Gupta wrote: > Please review this patch-series. I see no patch here :(
Re: [PATCH v2 03/10] mm/memory_hotplug: simplify page offlining
On Fri 04-09-20 12:21:34, Andrew Morton wrote: > On Fri, 4 Sep 2020 07:47:45 +0200 David Hildenbrand wrote: [...] > @@ -1589,9 +1567,7 @@ int __ref offline_pages(unsigned long st > reason = "failure to dissolve huge pages"; > goto failed_removal_isolated; > } > - /* check again */ > - ret = walk_system_ram_range(start_pfn, end_pfn - start_pfn, > - NULL, check_pages_isolated_cb); > + > /* >* per-cpu pages are drained in start_isolate_page_range, but if >* there are still pages that are not free, make sure that we > @@ -1604,15 +1580,15 @@ int __ref offline_pages(unsigned long st >* because has_unmovable_pages explicitly checks for >* PageBuddy on freed pages on other zones. >*/ > + ret = test_pages_isolated(start_pfn, end_pfn, MEMORY_OFFLINE); > if (ret) > drain_all_pages(zone); > } while (ret); Looks ok -- Michal Hocko SUSE Labs
[PATCH v9 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 1a950171a66f..58b2d610aadb 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -40,8 +40,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8831b964288f..c387aa1615ba 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -634,7 +633,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -902,7 +901,7 @@ static int add_metric(struct list_head *metric_list, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 62623a39cbec..491a5d78252d 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -52,6 +53,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v9 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 35 --- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..7a5d1bf543f8 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,37 +1,46 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { @@ -48,7 +57,7 @@ { "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.26.2
[PATCH v9 2/5] perf/jevents: Add new structure to pass json fields.
This patch adds new structure called 'json_event' inside jevents.c file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which make it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. Signed-off-by: Kajol Jain Reviewed-by: Andi Kleen Reviewed-by: John Garry --- tools/perf/pmu-events/jevents.c | 212 +++- 1 file changed, 97 insertions(+), 115 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index b9b938aaff16..db334b2fd896 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -52,6 +52,23 @@ int verbose; char *prog; +struct json_event { + char *name; + char *event; + char *desc; + char *long_desc; + char *pmu; + char *unit; + char *perpkg; + char *metric_expr; + char *metric_name; + char *metric_group; + char *deprecated; + char *metric_constraint; +}; + +typedef int (*func)(void *data, struct json_event *je); + int eprintf(int level, int var, const char *fmt, ...) { @@ -70,11 +87,6 @@ int eprintf(int level, int var, const char *fmt, ...) return ret; } -__attribute__((weak)) char *get_cpu_str(void) -{ - return NULL; -} - static void addfield(char *map, char **dst, const char *sep, const char *a, jsmntok_t *bt) { @@ -317,12 +329,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) close_table = 1; } -static int print_events_table_entry(void *data, char *name, char *event, - char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, - char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) +static int print_events_table_entry(void *data, struct json_event *je) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -334,30 +341,30 @@ static int print_events_table_entry(void *data, char *name, char *event, */ fprintf(outfp, "{\n"); - if (name) - fprintf(outfp, "\t.name = \"%s\",\n", name); - if (event) - fprintf(outfp, "\t.event = \"%s\",\n", event); - fprintf(outfp, "\t.desc = \"%s\",\n", desc); + if (je->name) + fprintf(outfp, "\t.name = \"%s\",\n", je->name); + if (je->event) + fprintf(outfp, "\t.event = \"%s\",\n", je->event); + fprintf(outfp, "\t.desc = \"%s\",\n", je->desc); fprintf(outfp, "\t.topic = \"%s\",\n", topic); - if (long_desc && long_desc[0]) - fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); - if (pmu) - fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); - if (unit) - fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); - if (metric_expr) - fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); - if (metric_name) - fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name); - if (metric_group) - fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); - if (deprecated) - fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); - if (metric_constraint) - fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); + if (je->long_desc && je->long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc); + if (je->pmu) + fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu); + if (je->unit) + fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); + if (je->perpkg) + fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->metric_expr) + fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); + if (je->metric_name) + fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name); + if (je->metric_group) + fprintf(outfp, "\t.metric_group = \"%s\",\n", je->metric_group); + if (je->deprecated) + fprintf(outfp, "\t.deprecated = \"%s\",\n", je->deprecated); + if (je->metric_constraint) + fprintf(outfp, "\t.metric_constraint = \"%s\",\n", je->metric_constraint); fprintf(outfp, "},\n"); return 0; @@ -379,17 +386,17 @@ struct event_struct { char *metric_constraint; }; -#define ADD_EVENT_FIELD(field) do { if (field) { \ - es->field = strdup(field); \ +#define ADD_EVENT_FIELD(field) do { if (je
[PATCH v9 1/5] perf/jevents: Remove jevents.h file
This patch removes jevents.h and makes json_events function static. Signed-off-by: Kajol Jain Reviewed-by: John Garry --- tools/perf/pmu-events/jevents.c | 3 +-- tools/perf/pmu-events/jevents.h | 23 --- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fc9c158bfa13..b9b938aaff16 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,7 +48,6 @@ #include #include "jsmn.h" #include "json.h" -#include "jevents.h" int verbose; char *prog; @@ -512,7 +511,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, } /* Call func with each event in the json file */ -int json_events(const char *fn, +static int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h deleted file mode 100644 index 2afc8304529e.. --- a/tools/perf/pmu-events/jevents.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef JEVENTS_H -#define JEVENTS_H 1 - -int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc, - char *long_desc, - char *pmu, - char *unit, char *perpkg, char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint), - void *data); -char *get_cpu_str(void); - -#ifndef min -#define min(x, y) ({\ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) -#endif - -#endif -- 2.26.2
[PATCH v9 3/5] perf jevents: Add support for parsing perchip/percore events
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 20 tools/perf/pmu-events/pmu-events.h | 6 ++ 2 files changed, 26 insertions(+) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index db334b2fd896..b6f0c13ae8c0 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,6 +48,7 @@ #include #include "jsmn.h" #include "json.h" +#include "pmu-events.h" int verbose; char *prog; @@ -60,6 +61,7 @@ struct json_event { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -67,6 +69,17 @@ struct json_event { char *metric_constraint; }; +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; + + pr_err("%s: Wrong AggregationMode value '%s'\n", prog, aggr_mode); + return -1; +} + typedef int (*func)(void *data, struct json_event *je); int eprintf(int level, int var, const char *fmt, ...) @@ -355,6 +368,8 @@ static int print_events_table_entry(void *data, struct json_event *je) fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); if (je->perpkg) fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(je->aggr_mode)); if (je->metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); if (je->metric_name) @@ -379,6 +394,7 @@ struct event_struct { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -408,6 +424,7 @@ struct event_struct { op(pmu);\ op(unit); \ op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -613,6 +630,8 @@ static int json_events(const char *fn, addfield(map, &je.unit, "", "", val); } else if (json_streq(map, field, "PerPkg")) { addfield(map, &je.perpkg, "", "", val); + } else if (json_streq(map, field, "AggregationMode")) { + addfield(map, &je.aggr_mode, "", "", val); } else if (json_streq(map, field, "Deprecated")) { addfield(map, &je.deprecated, "", "", val); } else if (json_streq(map, field, "MetricName")) { @@ -673,6 +692,7 @@ static int json_events(const char *fn, free(je.pmu); free(filter); free(je.perpkg); + free(je.aggr_mode); free(je.deprecated); free(je.unit); free(je.metric_expr); diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index c8f306b572f4..7da1a3743b77 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -2,6 +2,11 @@ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H +enum aggr_mode_class { + PerChip = 1, + PerCore +}; + /* * Describe each PMU event. Each CPU has a table of PMU events. */ @@ -14,6 +19,7 @@ struct pmu_event { const char *pmu; const char *unit; const char *perpkg; + const char *aggr_mode; const char *metric_expr; const char *metric_name; const char *metric_group; -- 2.26.2
[PATCH v9 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. This patchset also adds changes of adding new structure called 'json_event' inside jevents.c file to improve the callback prototype inside jevent file. Initially, whenever user want to add new field, they need to update in all function callback which makes it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. link to the RFC patch: https://lkml.org/lkml/2020/8/25/217 Changelog: v8 -> v9 - Free aggr_mode memory [Jiri Olsa]. v7 -> v8 - Change commit typo from jevents.h to jevents.c - Make json_events function static in first patch. v6 -> v7 - Remove min and get_cpu_str functions from jevents.c - Make json_events function static to solve warning part [John Garry]. - Add event attribute in json_events function to remove strcpy from real_event function, as suggested by Jiri Olsa. - Add warning while checking aggr_mode value [Jiri Olsa]. Kajol Jain (5): perf/jevents: Remove jevents.h file perf/jevents: Add new structure to pass json fields. perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 35 ++- tools/perf/pmu-events/jevents.c | 234 +- tools/perf/pmu-events/jevents.h | 23 -- tools/perf/pmu-events/pmu-events.h| 6 + tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 154 insertions(+), 159 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h -- 2.26.2
Re: [PATCH v8 3/5] perf jevents: Add support for parsing perchip/percore events
On 9/6/20 6:25 PM, Jiri Olsa wrote: > On Sun, Sep 06, 2020 at 04:50:02PM +0530, Kajol Jain wrote: > > SNIP > >> typedef int (*func)(void *data, struct json_event *je); >> >> int eprintf(int level, int var, const char *fmt, ...) >> @@ -355,6 +368,8 @@ static int print_events_table_entry(void *data, struct >> json_event *je) >> fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); >> if (je->perpkg) >> fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); >> +if (je->aggr_mode) >> +fprintf(outfp, "\t.aggr_mode = \"%d\",\n", >> convert(je->aggr_mode)); >> if (je->metric_expr) >> fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); >> if (je->metric_name) >> @@ -379,6 +394,7 @@ struct event_struct { >> char *pmu; >> char *unit; >> char *perpkg; >> +char *aggr_mode; >> char *metric_expr; >> char *metric_name; >> char *metric_group; >> @@ -408,6 +424,7 @@ struct event_struct { >> op(pmu);\ >> op(unit); \ >> op(perpkg); \ >> +op(aggr_mode); \ >> op(metric_expr);\ >> op(metric_name);\ >> op(metric_group); \ >> @@ -613,6 +630,8 @@ static int json_events(const char *fn, >> addfield(map, &je.unit, "", "", val); >> } else if (json_streq(map, field, "PerPkg")) { >> addfield(map, &je.perpkg, "", "", val); >> +} else if (json_streq(map, field, "AggregationMode")) { >> +addfield(map, &je.aggr_mode, "", "", val); > > I think you should free je.aggr_mode My bad, missed that part. Will send updated one. Thanks, Kajol Jain > > jirka > >> } else if (json_streq(map, field, "Deprecated")) { >> addfield(map, &je.deprecated, "", "", val); >> } else if (json_streq(map, field, "MetricName")) { >> diff --git a/tools/perf/pmu-events/pmu-events.h >> b/tools/perf/pmu-events/pmu-events.h >> index c8f306b572f4..7da1a3743b77 100644 >> --- a/tools/perf/pmu-events/pmu-events.h >> +++ b/tools/perf/pmu-events/pmu-events.h >> @@ -2,6 +2,11 @@ >> #ifndef PMU_EVENTS_H >> #define PMU_EVENTS_H >> >> +enum aggr_mode_class { >> +PerChip = 1, >> +PerCore >> +}; >> + >> /* >> * Describe each PMU event. Each CPU has a table of PMU events. >> */ >> @@ -14,6 +19,7 @@ struct pmu_event { >> const char *pmu; >> const char *unit; >> const char *perpkg; >> +const char *aggr_mode; >> const char *metric_expr; >> const char *metric_name; >> const char *metric_group; >> -- >> 2.26.2 >> >
Re: [PATCH v2 1/2] drm: allow limiting the scatter list size.
> > + /** > > +* @max_segment: > > +* > > +* Max size for scatter list segments. When unset the default > > +* (SCATTERLIST_MAX_SEGMENT) is used. > > +*/ > > + size_t max_segment; > > Is there no better place for this then "at the bottom"? drm_device is a > huge structure, piling stuff up randomly doesn't make it better :-) Moved next to the other gem fields for now (v3 posted). > I think ideally we'd have a gem substruct like we have on the modeset side > at least. Phew, that'll be quite some churn in the tree. And there aren't that many gem-related fields in struct drm_device. So you are looking for something like below (header changes only)? take care, Gerd diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index c455ef404ca6..950167ede98a 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -299,22 +299,8 @@ struct drm_device { /** @mode_config: Current mode config */ struct drm_mode_config mode_config; - /** @object_name_lock: GEM information */ - struct mutex object_name_lock; - - /** @object_name_idr: GEM information */ - struct idr object_name_idr; - - /** @vma_offset_manager: GEM information */ - struct drm_vma_offset_manager *vma_offset_manager; - - /** -* @max_segment: -* -* Max size for scatter list segments for GEM objects. When -* unset the default (SCATTERLIST_MAX_SEGMENT) is used. -*/ - size_t max_segment; + /** @gem_config: Current GEM config */ + struct drm_gem_config gem_config; /** @vram_mm: VRAM MM memory manager */ struct drm_vram_mm *vram_mm; diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 337a48321705..74129fb29fb8 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -39,6 +39,25 @@ #include +struct drm_gem_config { + /** @object_name_lock: GEM information */ + struct mutex object_name_lock; + + /** @object_name_idr: GEM information */ + struct idr object_name_idr; + + /** @vma_offset_manager: GEM information */ + struct drm_vma_offset_manager *vma_offset_manager; + + /** +* @max_segment: +* +* Max size for scatter list segments for GEM objects. When +* unset the default (SCATTERLIST_MAX_SEGMENT) is used. +*/ + size_t max_segment; +}; + struct drm_gem_object; /**
[PATCH v2] net: wireless: wlcore: fix support for IGTK key
Changeset 2b7aadd3b9e1 ("wlcore: Adding suppoprt for IGTK key in wlcore driver") added support for AEC CMAC cipher suite. However, this only works with the very newest firmware version (8.9.0.0.83). Such firmware weren't even pushed to linux-firmware git tree yet: https://git.ti.com/cgit/wilink8-wlan/wl18xx_fw/log/ Due to that, it causes a regression betwen Kernel 5.7 and 5.8: with such patch applied, WiFi stops working, and the Kernel starts printing this message every second: wlcore: PHY firmware version: Rev 8.2.0.0.242 wlcore: firmware booted (Rev 8.9.0.0.79) wlcore: ERROR command execute failure 14 [ cut here ] WARNING: CPU: 0 PID: 133 at drivers/net/wireless/ti/wlcore/main.c:795 wl12xx_queue_recovery_work.part.0+0x6c/0x74 [wlcore] Modules linked in: wl18xx wlcore mac80211 libarc4 cfg80211 rfkill snd_soc_hdmi_codec crct10dif_ce wlcore_sdio adv7511 cec kirin9xx_drm(C) kirin9xx_dw_drm_dsi(C) drm_kms_helper drm ip_tables x_tables ipv6 nf_defrag_ipv6 CPU: 0 PID: 133 Comm: kworker/0:1 Tainted: GWC5.8.0+ #186 Hardware name: HiKey970 (DT) Workqueue: events_freezable ieee80211_restart_work [mac80211] pstate: 6005 (nZCv daif -PAN -UAO BTYPE=--) pc : wl12xx_queue_recovery_work.part.0+0x6c/0x74 [wlcore] lr : wl12xx_queue_recovery_work+0x24/0x30 [wlcore] sp : 8000126c3a60 x29: 8000126c3a60 x28: 25de x27: 0010 x26: 0005 x25: 0001a5d49e80 x24: 892cf580 x23: 0001b7c12623 x22: 0001b6fcf2e8 x21: 0001b7e46200 x20: fffb x19: 0001a78e6400 x18: 0030 x17: 0001 x16: 0001 x15: 0001b7e46670 x14: x13: 8000926c37d7 x12: 8000126c37e0 x11: 800011e01000 x10: 8000120526d0 x9 : x8 : 3431206572756c69 x7 : 6166206574756365 x6 : 0c2c x5 : x4 : 0001bf1361e8 x3 : 0001bf1790b0 x2 : x1 : 0001a5d49e80 x0 : 0001 Call trace: wl12xx_queue_recovery_work.part.0+0x6c/0x74 [wlcore] wl12xx_queue_recovery_work+0x24/0x30 [wlcore] wl1271_cmd_set_sta_key+0x258/0x25c [wlcore] wl1271_set_key+0x7c/0x2dc [wlcore] wlcore_set_key+0xe4/0x360 [wlcore] wl18xx_set_key+0x48/0x1d0 [wl18xx] wlcore_op_set_key+0xa4/0x180 [wlcore] ieee80211_key_enable_hw_accel+0xb0/0x2d0 [mac80211] ieee80211_reenable_keys+0x70/0x110 [mac80211] ieee80211_reconfig+0xa00/0xca0 [mac80211] ieee80211_restart_work+0xc4/0xfc [mac80211] process_one_work+0x1cc/0x350 worker_thread+0x13c/0x470 kthread+0x154/0x160 ret_from_fork+0x10/0x30 ---[ end trace b1f722abf9af5919 ]--- wlcore: WARNING could not set keys wlcore: ERROR Could not add or replace key wlan0: failed to set key (4, ff:ff:ff:ff:ff:ff) to hardware (-5) wlcore: Hardware recovery in progress. FW ver: Rev 8.9.0.0.79 wlcore: pc: 0x0, hint_sts: 0x0040 count: 39 wlcore: down wlcore: down ieee80211 phy0: Hardware restart was requested mmc_host mmc0: Bus speed (slot 0) = 40Hz (slot req 40Hz, actual 40HZ div = 0) mmc_host mmc0: Bus speed (slot 0) = 2500Hz (slot req 2500Hz, actual 2500HZ div = 0) wlcore: PHY firmware version: Rev 8.2.0.0.242 wlcore: firmware booted (Rev 8.9.0.0.79) wlcore: ERROR command execute failure 14 [ cut here ] Fix it by adding some code that will check if the firmware version is at least version 8.9.0.0.83. Tested on Hikey 970. Fixes: 2b7aadd3b9e1 ("wlcore: Adding suppoprt for IGTK key in wlcore driver") Signed-off-by: Mauro Carvalho Chehab --- Hi Raz, Maybe this patch could be useful once firmware 8.9.0.0.83 is released. v2: change it to require minimal verson 8.9.0.0.83 for IGTK key drivers/net/wireless/ti/wlcore/main.c | 48 + drivers/net/wireless/ti/wlcore/wlcore.h | 2 ++ 2 files changed, 50 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index de6c8a7589ca..4332eaa1a733 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "wlcore.h" #include "debug.h" @@ -1082,6 +1083,45 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) return ret; } +static bool wl1271_check_aes_cmac_cypher(struct wl1271 *wl) +{ + int ver[5] = { }; + int ret; + const char *p = wl->chip.fw_ver_str; + + + /* The string starts with "Rev ". Ignore it */ + while (*p && !isdigit(*p)) + p++; + + ret = sscanf(p, "%d.%d.%d.%d.%d", +&ver[0], &ver[1], &ver[2], &ver[3], &ver[4]); + + if (ret != ARRAY_SIZE(ver)) { + wl1271_info("Parsed version: %d.%d.%d.%d.%d\n", + ver[0], ver
Re: [PATCH v2 4/5] perf record: Don't clear event's period if set by a term
On 4/09/20 8:43 am, Ian Rogers wrote: > On Tue, Aug 4, 2020 at 8:50 AM Ian Rogers wrote: >> On Tue, Aug 4, 2020 at 7:49 AM Adrian Hunter wrote: >>> On 4/08/20 4:33 pm, Ian Rogers wrote: On Tue, Aug 4, 2020 at 3:08 AM Adrian Hunter wrote: > On 28/07/20 11:57 am, Ian Rogers wrote: >> If events in a group explicitly set a frequency or period with leader >> sampling, don't disable the samples on those events. >> >> Prior to 5.8: >> perf record -e '{cycles/period=12345000/,instructions/period=6789000/}:S' > Might be worth explaining this use-case some more. > Perhaps add it to the leader sampling documentation for perf-list. > >> would clear the attributes then apply the config terms. In commit >> 5f34278867b7 leader sampling configuration was moved to after applying >> the >> config terms, in the example, making the instructions' event have its >> period >> cleared. >> This change makes it so that sampling is only disabled if configuration >> terms aren't present. >> >> Fixes: 5f34278867b7 ("perf evlist: Move leader-sampling configuration") >> Signed-off-by: Ian Rogers >> --- >> tools/perf/util/record.c | 28 >> 1 file changed, 20 insertions(+), 8 deletions(-) >> >> diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c >> index a4cc11592f6b..01d1c6c613f7 100644 >> --- a/tools/perf/util/record.c >> +++ b/tools/perf/util/record.c >> @@ -2,6 +2,7 @@ >> #include "debug.h" >> #include "evlist.h" >> #include "evsel.h" >> +#include "evsel_config.h" >> #include "parse-events.h" >> #include >> #include >> @@ -38,6 +39,9 @@ static void evsel__config_leader_sampling(struct evsel >> *evsel, struct evlist *ev >> struct perf_event_attr *attr = &evsel->core.attr; >> struct evsel *leader = evsel->leader; >> struct evsel *read_sampler; >> + struct evsel_config_term *term; >> + struct list_head *config_terms = &evsel->config_terms; >> + int term_types, freq_mask; >> >> if (!leader->sample_read) >> return; >> @@ -47,16 +51,24 @@ static void evsel__config_leader_sampling(struct >> evsel *evsel, struct evlist *ev >> if (evsel == read_sampler) >> return; >> >> + /* Determine the evsel's config term types. */ >> + term_types = 0; >> + list_for_each_entry(term, config_terms, list) { >> + term_types |= 1 << term->type; >> + } >> /* >> - * Disable sampling for all group members other than the leader in >> - * case the leader 'leads' the sampling, except when the leader is >> an >> - * AUX area event, in which case the 2nd event in the group is the >> one >> - * that 'leads' the sampling. >> + * Disable sampling for all group members except those with >> explicit >> + * config terms or the leader. In the case of an AUX area event, >> the 2nd >> + * event in the group is the one that 'leads' the sampling. >>*/ >> - attr->freq = 0; >> - attr->sample_freq= 0; >> - attr->sample_period = 0; >> - attr->write_backward = 0; >> + freq_mask = (1 << EVSEL__CONFIG_TERM_FREQ) | (1 << >> EVSEL__CONFIG_TERM_PERIOD); >> + if ((term_types & freq_mask) == 0) { > It would be nicer to have a helper e.g. > > if (!evsel__have_config_term(evsel, FREQ) && > !evsel__have_config_term(evsel, PERIOD)) { Sure. The point of doing it this way was to avoid repeatedly iterating over the config term list. >>> But perhaps it is premature optimization >> The alternative is more loc. I think we can bike shed on this but it's >> not really changing the substance of the change. I'm keen to try to be >> efficient where we can as we see issues at scale. >> >> Thanks, >> Ian > Ping. Do we want to turn this into multiple O(N) searches using a > helper rather than 1 as coded here? Actually max. 30 iterations vs max. 15 iterations for the 15 current possible config terms. At least please don't open code the config term implementation details. For example, make evsel__have_config_term() accept multiple terms or introduce u64 term_mask = evsel__config_term_mask(evsel); has_config_term(term_mask, FREQ) etc or whatever. > > Thanks, > Ian > >> + attr->freq = 0; >> + attr->sample_freq= 0; >> + attr->sample_period = 0; > If we are not sampling, then maybe we should also put here: > > attr->write_backward = 0; > >> + } > Then, if we are sampling this evsel shouldn't the backward setting > match the leader? e.g. > > if (attr->sample_freq) >
Re: [PATCH v1 2/2] fbdev: radeonfb:use generic power management
Re: [PATCH v1 1/2] video: fbdev: aty: radeon_pm: remove redundant CONFIG_PM container
Re: [PATCH] crypto: sa2ul - Select CRYPTO_AUTHENC
On 9/7/2020 11:52 AM, Herbert Xu wrote: Resend with new subject. Thanks Herbert. Reviewed-by: Keerthy ---8<--- The sa2ul driver uses crypto_authenc_extractkeys and therefore must select CRYPTO_AUTHENC. Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver") Reported-by: kernel test robot Signed-off-by: Herbert Xu diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index aa3a4ed07a66..c2950127def6 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -873,6 +873,7 @@ config CRYPTO_DEV_SA2UL select CRYPTO_AES select CRYPTO_AES_ARM64 select CRYPTO_ALGAPI + select CRYPTO_AUTHENC select HW_RANDOM select SG_SPLIT help
[PATCH v3 1/2] drm: allow limiting the scatter list size.
Add max_segment argument to drm_prime_pages_to_sg(). When set pass it through to the __sg_alloc_table_from_pages() call, otherwise use SCATTERLIST_MAX_SEGMENT. Also add max_segment field to drm driver and pass it to drm_prime_pages_to_sg() calls in drivers and helpers. v2: place max_segment in drm driver not gem object. v3: move max_segment next to the other gem fields. Signed-off-by: Gerd Hoffmann --- include/drm/drm_device.h| 8 include/drm/drm_prime.h | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 3 ++- drivers/gpu/drm/drm_gem_shmem_helper.c | 3 ++- drivers/gpu/drm/drm_prime.c | 10 +++--- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 3 ++- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 3 ++- drivers/gpu/drm/msm/msm_gem.c | 3 ++- drivers/gpu/drm/msm/msm_gem_prime.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_prime.c | 3 ++- drivers/gpu/drm/radeon/radeon_prime.c | 3 ++- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 6 -- drivers/gpu/drm/tegra/gem.c | 3 ++- drivers/gpu/drm/vgem/vgem_drv.c | 3 ++- drivers/gpu/drm/xen/xen_drm_front_gem.c | 3 ++- 15 files changed, 43 insertions(+), 17 deletions(-) diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index f4f68e7a9149..c455ef404ca6 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -308,6 +308,14 @@ struct drm_device { /** @vma_offset_manager: GEM information */ struct drm_vma_offset_manager *vma_offset_manager; + /** +* @max_segment: +* +* Max size for scatter list segments for GEM objects. When +* unset the default (SCATTERLIST_MAX_SEGMENT) is used. +*/ + size_t max_segment; + /** @vram_mm: VRAM MM memory manager */ struct drm_vram_mm *vram_mm; diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index 9af7422b44cf..2c3689435cb4 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -88,7 +88,8 @@ void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr); int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma); -struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages); +struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages, + size_t max_segment); struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj, int flags); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 519ce4427fce..8f6a647757e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -303,7 +303,8 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, switch (bo->tbo.mem.mem_type) { case TTM_PL_TT: sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, - bo->tbo.num_pages); + bo->tbo.num_pages, + obj->dev->max_segment); if (IS_ERR(sgt)) return sgt; diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 4b7cfbac4daa..8f47b41b0b2f 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -656,7 +656,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj) WARN_ON(shmem->base.import_attach); - return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT); + return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT, +obj->dev->max_segment); } EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 1693aa7c14b5..27c783fd6633 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -802,7 +802,8 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { * * This is useful for implementing &drm_gem_object_funcs.get_sg_table. */ -struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages) +struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages, + size_t max_segment) { struct sg_table *sg = NULL; int ret; @@ -813,8 +814,11 @@ struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_page goto out; } - ret = sg_alloc_table_from_pages(sg, pages, nr_pages, 0, - nr_pages << PAGE_SHIFT, GFP_KERNEL); + if (max_segment == 0 || max_segment > SCA
Re: [PATCH v1 0/2] video: fbdev: radeonfb: PCI PM framework upgrade and fix-ups.
Please review this patch-series. Thank you Vaibhav Gupta
[PATCH v3 2/2] drm/virtio: set max_segment
When initializing call virtio_max_dma_size() to figure the scatter list limit. Needed to make virtio-gpu work properly with SEV. v2: place max_segment in drm driver not gem object. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_kms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 75d0dc2f6d28..151471acdfcf 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -167,6 +167,7 @@ int virtio_gpu_init(struct drm_device *dev) DRM_ERROR("failed to alloc vbufs\n"); goto err_vbufs; } + dev->max_segment = virtio_max_dma_size(vgdev->vdev); /* get display info */ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, -- 2.27.0
[PATCH net] can: j1939: j1939_sk_bind(): return failure if netdev is down
When a netdev down event occurs after a successful call to j1939_sk_bind(), j1939_netdev_notify() can handle it correctly. But if the netdev already in down state before calling j1939_sk_bind(), j1939_sk_release() will stay in wait_event_interruptible() blocked forever. Because in this case, j1939_netdev_notify() won't be called and j1939_tp_txtimer() won't call j1939_session_cancel() or other function to clear session for ENETDOWN error, this lead to mismatch of j1939_session_get/put() and jsk->skb_pending will never decrease to zero. To reproduce it use following commands: 1. ip link add dev vcan0 type vcan 2. j1939acd -r 100,80-120 1122334455667788 vcan0 3. presses ctrl-c and thread will be blocked forever This patch adds check for ndev->flags in j1939_sk_bind() to avoid this kind of situation and return with -ENETDOWN. Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") Signed-off-by: Zhang Changzhong --- net/can/j1939/socket.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c index 1be4c89..f239665 100644 --- a/net/can/j1939/socket.c +++ b/net/can/j1939/socket.c @@ -475,6 +475,12 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len) goto out_release_sock; } + if (!(ndev->flags & IFF_UP)) { + dev_put(ndev); + ret = -ENETDOWN; + goto out_release_sock; + } + priv = j1939_netdev_start(ndev); dev_put(ndev); if (IS_ERR(priv)) { -- 2.9.5
RE: [RESEND][PATCH v3] x86/apic/flat64: Add back the early_param("apic", parse_apic)
> From: Thomas Gleixner > Sent: Friday, July 17, 2020 6:03 AM > [...] Hi, I'm very sorry for this extremely late reply -- I was sidetracked by something else and I just had a chance to revisit the issue. Thank you tglx for the comments and suggestions, which I think are reasonable. I realized this patch is problematic. The good news is that the LAPIC emulation bug has been fixed in the latest version of Hyper-V and now kdump can work reliably. I think the hypervisor fix would be backported to old Hyper-V versions, so hopefully this won't be an issue over time. Thanks, -- Dexuan
[PATCH] crypto: sun4i-ss - Fix SHA1 hash on A33-variant with BE CPU
On Sun, Sep 06, 2020 at 04:52:24PM +0800, kernel test robot wrote: > > >> drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:483:35: sparse: sparse: > >> incorrect type in assignment (different base types) @@ expected > >> unsigned int [assigned] [usertype] v @@ got restricted __le32 > >> [usertype] @@ >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:483:35: sparse: > expected unsigned int [assigned] [usertype] v >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:483:35: sparse: got > restricted __le32 [usertype] >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:485:35: sparse: sparse: > incorrect type in assignment (different base types) @@ expected unsigned > int [assigned] [usertype] v @@ got restricted __be32 [usertype] @@ >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:485:35: sparse: > expected unsigned int [assigned] [usertype] v >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:485:35: sparse: got > restricted __be32 [usertype] >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:490:27: sparse: sparse: > incorrect type in assignment (different base types) @@ expected unsigned > int [addressable] [assigned] [usertype] v @@ got restricted __le32 > [usertype] @@ >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:490:27: sparse: > expected unsigned int [addressable] [assigned] [usertype] v >drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c:490:27: sparse: got > restricted __le32 [usertype] This appears to be a genuine bug, on big-endian CPUs at least. ---8<--- When the hash is written out on the A33 variant, it is incorrectly swabbed on big-endian CPUs, when it should simply be written out as is because it's already in the right format. This was caught by sparse warnings. Instead of using cpu_to_Xe32 followed by a memcpy, this patch converts the final hash write to use put_unaligned instead. This simplifies the code and makes the A33 variant handling a lot clearer. This patch also fixes the incorrect endianness marking on wb, although this should have no effect in the genereated code. Fixes: 1e02e6fbdadb ("crypto: sun4i-ss - add the A33 variant of SS") Reported-by: kernel test robot Signed-off-by: Herbert Xu diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c index dc35edd90034..84f7921de577 100644 --- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c +++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c @@ -9,6 +9,7 @@ * You could find the datasheet in Documentation/arm/sunxi.rst */ #include "sun4i-ss.h" +#include #include /* This is a totally arbitrary value */ @@ -196,7 +197,7 @@ static int sun4i_hash(struct ahash_request *areq) struct sg_mapping_iter mi; int in_r, err = 0; size_t copied = 0; - __le32 wb = 0; + u32 wb = 0; dev_dbg(ss->dev, "%s %s bc=%llu len=%u mode=%x wl=%u h0=%0x", __func__, crypto_tfm_alg_name(areq->base.tfm), @@ -408,7 +409,7 @@ static int sun4i_hash(struct ahash_request *areq) nbw = op->len - 4 * nwait; if (nbw) { - wb = cpu_to_le32(*(u32 *)(op->buf + nwait * 4)); + wb = le32_to_cpup((__le32 *)(op->buf + nwait * 4)); wb &= GENMASK((nbw * 8) - 1, 0); op->byte_count += nbw; @@ -417,7 +418,7 @@ static int sun4i_hash(struct ahash_request *areq) /* write the remaining bytes of the nbw buffer */ wb |= ((1 << 7) << (nbw * 8)); - bf[j++] = le32_to_cpu(wb); + ((__le32 *)bf)[j++] = cpu_to_le32(wb); /* * number of space to pad to obtain 64o minus 8(size) minus 4 (final 1) @@ -479,16 +480,16 @@ static int sun4i_hash(struct ahash_request *areq) /* Get the hash from the device */ if (op->mode == SS_OP_SHA1) { for (i = 0; i < 5; i++) { + v = readl(ss->base + SS_MD0 + i * 4); if (ss->variant->sha1_in_be) - v = cpu_to_le32(readl(ss->base + SS_MD0 + i * 4)); + put_unaligned(v, areq->result + i * 4); else - v = cpu_to_be32(readl(ss->base + SS_MD0 + i * 4)); - memcpy(areq->result + i * 4, &v, 4); + put_unaligned_be32(v, areq->result + i * 4); } } else { for (i = 0; i < 4; i++) { - v = cpu_to_le32(readl(ss->base + SS_MD0 + i * 4)); - memcpy(areq->result + i * 4, &v, 4); + v = readl(ss->base + SS_MD0 + i * 4); + put_unaligned_le32(v, areq->result + i * 4); } } -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[PATCH] crypto: sa2ul - Select CRYPTO_AUTHENC
Resend with new subject. ---8<--- The sa2ul driver uses crypto_authenc_extractkeys and therefore must select CRYPTO_AUTHENC. Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver") Reported-by: kernel test robot Signed-off-by: Herbert Xu diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index aa3a4ed07a66..c2950127def6 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -873,6 +873,7 @@ config CRYPTO_DEV_SA2UL select CRYPTO_AES select CRYPTO_AES_ARM64 select CRYPTO_ALGAPI + select CRYPTO_AUTHENC select HW_RANDOM select SG_SPLIT help -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH v3] usb: dwc3: Stop active transfers before halting the controller
Hi, Wesley Cheng writes: > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c > index 59f2e8c31bd1..456aa87e8778 100644 > --- a/drivers/usb/dwc3/ep0.c > +++ b/drivers/usb/dwc3/ep0.c > @@ -197,7 +197,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct > usb_request *request, > int ret; > > spin_lock_irqsave(&dwc->lock, flags); > - if (!dep->endpoint.desc) { > + if (!dep->endpoint.desc || !dwc->pullups_connected) { this looks odd. If we don't have pullups connected, we shouldn't have a descriptor, likewise if we don't have a a description, we haven't been enumerated, therefore we shouldn't have pullups connected. What am I missing here? > @@ -1926,6 +1926,21 @@ static int dwc3_gadget_set_selfpowered(struct > usb_gadget *g, > return 0; > } > > +static void dwc3_stop_active_transfers(struct dwc3 *dwc) > +{ > + u32 epnum; > + > + for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) { dwc3 knows the number of endpoints available in the HW. Use dwc->num_eps instead. > @@ -1971,6 +1986,8 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int > is_on, int suspend) > return 0; > } > > +static void __dwc3_gadget_stop(struct dwc3 *dwc); > + > static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) > { > struct dwc3 *dwc = gadget_to_dwc(g); > @@ -1994,9 +2011,37 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, > int is_on) > } > } > > + /* > + * Synchronize and disable any further event handling while controller > + * is being enabled/disabled. > + */ > + disable_irq(dwc->irq_gadget); why isn't dwc3_gadget_disable_irq() enough? > spin_lock_irqsave(&dwc->lock, flags); spin_lock_irqsave() will disable interrupts, why disable_irq() above? > + /* Controller is not halted until pending events are acknowledged */ > + if (!is_on) { > + u32 count; > + > + /* > + * The databook explicitly mentions for a device-initiated > + * disconnect sequence, the SW needs to ensure that it ends any > + * active transfers. > + */ make this a little better by mentioning the version and section of the databook you're reading. That makes it easier for future reference. Also, use an actual quote from the databook, along the lines of: /* * Synopsys DesignWare Cores USB3 Databook Revision * X.YYa states in section W.Z that "device-initiated * disconnect " */ > + dwc3_stop_active_transfers(dwc); > + __dwc3_gadget_stop(dwc); > + > + count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); > + count &= DWC3_GEVNTCOUNT_MASK; > + if (count > 0) { > + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); > + dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % > + dwc->ev_buf->length; > + } don't duplicate code. Add a patch before this extracting this into helper and use it for both irq handler and gadget pullup. > + } > + > ret = dwc3_gadget_run_stop(dwc, is_on, false); > spin_unlock_irqrestore(&dwc->lock, flags); > + enable_irq(dwc->irq_gadget); > > return ret; > } > @@ -3100,6 +3145,8 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 > *dwc) > } > > dwc3_reset_gadget(dwc); > + /* Stop any active/pending transfers when receiving bus reset */ unnecessary comment. We're calling a function named "stop active transfers" from within the "bus reset handler". -- balbi signature.asc Description: PGP signature
Re: [PATCH] /dev/zero: also implement ->read
On Mon, Sep 07, 2020 at 12:34:37AM +0200, Rasmus Villemoes wrote: > On 03/09/2020 17.59, Christoph Hellwig wrote: > > Christophe reported a major speedup due to avoiding the iov_iter > > overhead, so just add this trivial function. Note that /dev/zero > > already implements both an iter and non-iter writes so this just > > makes it more symmetric. > > > > Christophe Leroy > > ?-by ? Suggested-by, > > +static ssize_t read_zero(struct file *file, char __user *buf, > > +size_t count, loff_t *ppos) > > +{ > > + size_t cleared = 0; > > + > > + while (count) { > > + size_t chunk = min_t(size_t, count, PAGE_SIZE); > > + > > + if (clear_user(buf + cleared, chunk)) > > + return cleared ? cleared : -EFAULT; > > Probably nobody really cares, but currently doing > > read(fd, &unmapped_page - 5, 123); > > returns 5, and those five bytes do get cleared; if I'm reading the above > right you'd return -EFAULT for that case. > > > > + cleared += chunk; > > + count -= chunk; > > + > > + if (signal_pending(current)) > > + return cleared ? cleared : -ERESTARTSYS; > > I can't see how we can get here without 'cleared' being positive, so > this can just be 'return cleared' (and if you fix the above EFAULT case > to more accurately track how much got cleared, there's probably no > longer any code to be symmetric with anyway). Yeah, I'll fix these up and resend.
Re: [PATCH] RISC-V: Allow drivers to provide custom read_cycles64 for M-mode kernel
On Sat, Sep 05, 2020 at 11:05:48AM +0530, Anup Patel wrote: > Your patch will also break if the SOC specific timer has a 32bit > free-running counter > unlike the 64bit free-running counter found on CLINT. > > I guess it's better to let the SOC timer driver provide the > method/function to read the > free-running counter. Seriously, build the interfaces once you know the consumers. Don't build pie in the sky interfaces just because you can, because that is what creates all the problems. And of coruse at least for IPIs which absolutely are performance criticical we need a standard interface (one that doesn't suck as much as the SBI detour with the four extra context switches). But I guess I have already given up on RISC-V because the incompetency about things like the irq design are just so horrible that it isn't worth bothering any more.
Re: [PATCH v7 3/3] fpga: dfl: add support for N3000 Nios private feature
On Fri, Sep 04, 2020 at 05:45:12PM -0700, Moritz Fischer wrote: > Hi Xu, > > On Wed, Aug 19, 2020 at 03:45:21PM +0800, Xu Yilun wrote: > > This patch adds support for the Nios handshake private feature on Intel > > PAC (Programmable Acceleration Card) N3000. > > > > The Nios is the embedded processor on the FPGA card. This private feature > > provides a handshake interface to FPGA Nois firmware, which receives > FPGA *NIOS* or *Nios* I think ;-) Thanks for catching the misspelling. > > +Configuring the ethernet retimer > > + > > + > > +The Intel PAC N3000 is a FPGA based SmartNIC platform which could be > > programmed > > +to various configurations (with different link numbers and speeds, e.g. > > 8x10G, > > +4x25G ...). And the retimer chips should also be configured > > correspondingly by > > +Nios firmware. There are 2 retimer chips on the board, each of them > > supports 4 > > +links. For example, in 8x10G configuration, the 2 retimer chips are both > > set to > > +4x10G mode, while in 4x25G configuration, retimer A is set to 4x25G and > > retimer > > +B is in reset. For now, the Nios firmware only supports 10G and 25G mode > > +setting for the retimer chips. > Make sure your API above exposes all of that. Yes. I could add the sysfs interfaces for query of the retimer mode. > > +Sysfs Attributes > > + > > + > > +The driver creates the sysfs file in /sys/bus/dfl/devices/dfl_dev.X/ > > + > > +* fec_mode: > > + Read-only. It shows the FEC mode of the 25G links of the ethernet > > retimers. > > + The possible values are the same as the fec_mode module parameter. An > > extra > > + value "not supported" is returned if firmware version major < 3, or no > > link > > + is configured to 25G. > > This seems somewhat duplicate, runs the risk to get out of sync with the > ABI doc? Yes. I could just reference the file in Documentation/ABI > > +static ssize_t fec_mode_show(struct device *dev, > > +struct device_attribute *attr, char *buf) > > +{ > > + struct n3000_nios *ns = dev_get_drvdata(dev); > > + unsigned int val, retimer_a_mode, retimer_b_mode, fec_mode; > Can you make this reverse x-mas tree if possible? Yes, I'll change it. > > +static int init_error_detected(struct n3000_nios *ns) > Do you want to make the function either bool, or the return values ints? I can make it bool. > > +{ > > + unsigned int val; > > + > > + if (regmap_read(ns->regmap, PKVL_A_MODE_STS, &val)) > > + return true; > > + > > + if (!IS_MODE_STATUS_OK(val)) > > + return true; > > + > > + if (regmap_read(ns->regmap, PKVL_B_MODE_STS, &val)) > > + return true; > > + > > + if (!IS_MODE_STATUS_OK(val)) > > + return true; > > + > > + return false; > > +} > > + if (val == 0) { > > + dev_err(dev, "Nios version reg = 0x%x, skip INIT_DONE check, > > but the retimer may be uninitialized\n", > This looks long, any chance you can linebreak this? I tried to break the line by dev_err(dev, "XXX" "XXX", val); But checkpatch says "WARNING: quoted string split across lines". I see checkpatch allows long lines for logging functions, so could we keep it unchanged? > > +struct spi_board_info m10_n3000_info = { > > + .modalias = "m10-n3000", > Did I miss the patch for this, or did this only go to the SPI folks? I didn't send the MAX 10 patchset in fpga domain, It goes to the SPI & MFD maintainers, please see: https://lkml.org/lkml/2020/8/19/172 The regmap-spi-avmm has been applied for linux-next. The MAX 10 base driver is under review. > > + .max_speed_hz = 1250, > > + .bus_num = 0, > > + .chip_select = 0, > > +}; Thanks, Yilun.
drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c:78:62: sparse: sparse: Using plain integer as NULL pointer
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: f4d51dffc6c01a9e94650d95ce0104964f8ae822 commit: a66cbdd6573db8515735d37793c22605432c346d mt76: mt7615: introduce mt7663s support date: 7 weeks ago config: ia64-randconfig-s032-20200907 (attached as .config) compiler: ia64-linux-gcc (GCC) 9.3.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.2-191-g10164920-dirty git checkout a66cbdd6573db8515735d37793c22605432c346d # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=ia64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot sparse warnings: (new ones prefixed by >>) >> drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c:78:62: sparse: sparse: >> Using plain integer as NULL pointer drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c:110:62: sparse: sparse: Using plain integer as NULL pointer -- >> drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c:243:58: sparse: >> sparse: Using plain integer as NULL pointer drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c:270:58: sparse: sparse: Using plain integer as NULL pointer # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a66cbdd6573db8515735d37793c22605432c346d git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git git fetch --no-tags linus master git checkout a66cbdd6573db8515735d37793c22605432c346d vim +78 drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c 65 66 int mt7663s_driver_own(struct mt7615_dev *dev) 67 { 68 struct sdio_func *func = dev->mt76.sdio.func; 69 struct mt76_phy *mphy = &dev->mt76.phy; 70 u32 status; 71 int ret; 72 73 if (!test_and_clear_bit(MT76_STATE_PM, &mphy->state)) 74 goto out; 75 76 sdio_claim_host(func); 77 > 78 sdio_writel(func, WHLPCR_FW_OWN_REQ_CLR, MCR_WHLPCR, 0); 79 80 ret = readx_poll_timeout(mt7663s_read_pcr, dev, status, 81 status & WHLPCR_IS_DRIVER_OWN, 2000, 100); 82 if (ret < 0) { 83 dev_err(dev->mt76.dev, "Cannot get ownership from device"); 84 set_bit(MT76_STATE_PM, &mphy->state); 85 sdio_release_host(func); 86 87 return ret; 88 } 89 90 sdio_release_host(func); 91 92 out: 93 dev->pm.last_activity = jiffies; 94 95 return 0; 96 } 97 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
RE: [PATCH v3 00/16] arm/arm64: Turning IPIs into normal interrupts
Hi Marc. I am interested in this feature. I have confirmed this patch works fine on Fujitsu FX1000. Thanks for creating it. I look forward to the day when this patch is merged. We plan to post a patch that implements IPI for CPU stop Interrupt (for crash dump) with pseudo NMI. Tested-by: Hitomi Hasegawa Thanks. -Original Message- From: linux-arm-kernel On Behalf Of Marc Zyngier Sent: Tuesday, September 1, 2020 11:43 PM To: linux-arm-ker...@lists.infradead.org; linux-kernel@vger.kernel.org Cc: Sumit Garg ; kernel-t...@android.com; Florian Fainelli ; Russell King ; Jason Cooper ; Saravana Kannan ; Andrew Lunn ; Catalin Marinas ; Gregory Clement ; Thomas Gleixner ; Will Deacon ; Valentin Schneider Subject: [PATCH v3 00/16] arm/arm64: Turning IPIs into normal interrupts For as long as SMP ARM has existed, IPIs have been handled as something special. The arch code and the interrupt controller exchange a couple of hooks (one to generate an IPI, another to handle it). Although this is perfectly manageable, it prevents the use of features that we could use if IPIs were Linux IRQs (such as pseudo-NMIs). It also means that each interrupt controller driver has to follow an architecture-specific interface instead of just implementing the base irqchip functionalities. The arch code also duplicates a number of things that the core irq code already does (such as calling set_irq_regs(), irq_enter()...). This series tries to remedy this on arm/arm64 by offering a new registration interface where the irqchip gives the arch code a range of interrupts to use for IPIs. The arch code requests these as normal per-cpu interrupts. The bulk of the work is at the interrupt controller level, where all 5 irqchips used on arm+SMP/arm64 get converted. Finally, we drop the legacy registration interface as well as the custom statistics accounting. Note that I have had a look at providing a "generic" interface by expanding the kernel/irq/ipi.c bag of helpers, but so far all irqchips have very different requirements, so there is hardly anything to consolidate for now. Maybe some as hip04 and the Marvell horror get cleaned up (the latter certainly could do with a good dusting). This has been tested on a bunch of 32 and 64bit guests (GICv2, GICv3), as well as 64bit bare metal (GICv3). The RPi part has only been tested in QEMU as a 64bit guest, while the HiSi and Marvell parts have only been compile-tested. I'm aiming for 5.10 for this, so any comment would be appreciated. * From v2: - Tidied up the arch code (__read_mostly for the IPI handling data, WARN_ON_ONCE on setup and teardown), dropped spurious prototype on 32bit - Prevent IPIs from being forwarded to VCPUs - Merged the GIC affinity fix, hence one less patch - Added RBs from Valentin * From v1: - Clarified the effect of nesting irq_enter/exit (Russell) - Changed the point where we tear IPIs down on (Valentin) - IPIs are no longer accessible from DT - HIP04 and Armada 370-XP have been converted, but are untested - arch-specific kstat accounting is removed - ARM's legacy interface is dropped Marc Zyngier (16): genirq: Add fasteoi IPI flow genirq: Allow interrupts to be excluded from /proc/interrupts arm64: Allow IPIs to be handled as normal interrupts ARM: Allow IPIs to be handled as normal interrupts irqchip/gic-v3: Describe the SGI range irqchip/gic-v3: Configure SGIs as standard interrupts irqchip/gic: Refactor SMP configuration irqchip/gic: Configure SGIs as standard interrupts irqchip/gic-common: Don't enable SGIs by default irqchip/bcm2836: Configure mailbox interrupts as standard interrupts irqchip/hip04: Configure IPIs as standard interrupts irqchip/armada-370-xp: Configure IPIs as standard interrupts arm64: Kill __smp_cross_call and co arm64: Remove custom IRQ stat accounting ARM: Kill __smp_cross_call and co ARM: Remove custom IRQ stat accounting arch/arm/Kconfig| 1 + arch/arm/include/asm/hardirq.h | 17 -- arch/arm/include/asm/smp.h | 5 +- arch/arm/kernel/smp.c | 135 +- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/hardirq.h| 9 - arch/arm64/include/asm/irq_work.h | 4 +- arch/arm64/include/asm/smp.h| 6 +- arch/arm64/kernel/smp.c | 121 - drivers/irqchip/irq-armada-370-xp.c | 262 +++- drivers/irqchip/irq-bcm2836.c | 151 +--- drivers/irqchip/irq-gic-common.c| 3 - drivers/irqchip/irq-gic-v3.c| 104 ++- drivers/irqchip/irq-gic.c | 177 +++ drivers/irqchip/irq-hip04.c | 89 +- include/linux/irq.h | 5 +- kernel/irq/chip.c | 27 +++ kernel/irq/debugfs.c| 1 + kernel/irq/proc.c | 2 +- kernel/irq/settings.h | 7 + 20 files changed, 720 insert
Re: [PATCH] cpufreq,cppc: fix issue when hotplugging out policy->cpu
On 04-09-20, 10:43, Ionela Voinescu wrote: > Do you know why it was designed this way in the first place? No. > I assumed it was designed like this (per-cpu cppc_cpudata structures) to > allow for the future addition of support for the HW_ALL CPPC coordination > type. In that case you can still have PSD (dependency) domains but the > desired performance controls would be per-cpu, with the coordination > done in hardware/firmware. So, in the HW_ALL case you'd end up having > different performance controls even for CPUs in the same policy. > Currently the CPPC driver only supports SW_ANY which is the traditional > cpufreq approach. Then the person who would add that feature will take care of fixing the issues then. We should make sure we handle the current use-case optimally. And a per-cpu thing isn't working well for that. -- viresh
Re: [PATCH v2 2/3] soc: sifive: Add SiFive specific Cadence DDR controller driver
On Mon, Sep 07, 2020 at 11:17:58AM +0530, Yash Shah wrote: > Add a driver to manage the Cadence DDR controller present on SiFive SoCs > At present the driver manages the EDAC feature of the DDR controller. > Additional features may be added to the driver in future to control > other aspects of the DDR controller. So if this is a generic(ish) Cadence IP block shouldn't it be named Cadence and made generic? Or is the frontend somehow SiFive specific?
Re: [PATCH v3 12/14] dt-bindings: mtd: gpmi-nand: Fix matching of clocks on different SoCs
On Fri, Sep 04, 2020 at 04:36:39PM -0600, Rob Herring wrote: > On Fri, Sep 4, 2020 at 9:25 AM Krzysztof Kozlowski wrote: > > > > Driver requires different amount of clocks for different SoCs. Describe > > these requirements properly to fix dtbs_check warnings like: > > > > arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dt.yaml: > > nand-controller@33002000: clock-names:1: 'gpmi_apb' was expected > > > > Signed-off-by: Krzysztof Kozlowski > > > > --- > > > > Changes since v1: > > 1. Do not require order of clocks (use pattern). > > To the extent that you can, you should fix the order in dts files > first. If we just adjust the schemas to match the dts files, then > what's the point? The DTSes do not have mixed order of clocks between each other, as fair as I remember. It was fix after Sasha Hauer comment that order is not necessarily good. We have the clock-names property, why enforcing the order? > > > --- > > .../devicetree/bindings/mtd/gpmi-nand.yaml| 76 +++ > > 1 file changed, 61 insertions(+), 15 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.yaml > > b/Documentation/devicetree/bindings/mtd/gpmi-nand.yaml > > index 28ff8c581837..e08e0a50929e 100644 > > --- a/Documentation/devicetree/bindings/mtd/gpmi-nand.yaml > > +++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.yaml > > @@ -9,9 +9,6 @@ title: Freescale General-Purpose Media Interface (GPMI) > > binding > > maintainers: > >- Han Xu > > > > -allOf: > > - - $ref: "nand-controller.yaml" > > - > > description: | > >The GPMI nand controller provides an interface to control the NAND > >flash chips. The device tree may optionally contain sub-nodes > > @@ -58,22 +55,10 @@ properties: > >clocks: > > minItems: 1 > > maxItems: 5 > > -items: > > - - description: SoC gpmi io clock > > - - description: SoC gpmi apb clock > > - - description: SoC gpmi bch clock > > - - description: SoC gpmi bch apb clock > > - - description: SoC per1 bch clock > > > >clock-names: > > minItems: 1 > > maxItems: 5 > > -items: > > - - const: gpmi_io > > - - const: gpmi_apb > > - - const: gpmi_bch > > - - const: gpmi_bch_apb > > - - const: per1_bch > > > >fsl,use-minimum-ecc: > > type: boolean > > @@ -107,6 +92,67 @@ required: > > > > unevaluatedProperties: false > > > > +allOf: > > + - $ref: "nand-controller.yaml" > > + > > + - if: > > + properties: > > +compatible: > > + contains: > > +enum: > > + - fsl,imx23-gpmi-nand > > + - fsl,imx28-gpmi-nand > > +then: > > + properties: > > +clocks: > > + items: > > +- description: SoC gpmi io clock > > +clock-names: > > + items: > > +- const: gpmi_io > > + > > + - if: > > + properties: > > +compatible: > > + contains: > > +enum: > > + - fsl,imx6q-gpmi-nand > > + - fsl,imx6sx-gpmi-nand > > +then: > > + properties: > > +clocks: > > + items: > > +- description: SoC gpmi io clock > > +- description: SoC gpmi apb clock > > +- description: SoC gpmi bch clock > > +- description: SoC gpmi bch apb clock > > +- description: SoC per1 bch clock > > +clock-names: > > + items: > > +- pattern: "^(gpmi_(io|apb|bch|bch_apb)|per1_bch)$" > > +- pattern: "^(gpmi_(io|apb|bch|bch_apb)|per1_bch)$" > > +- pattern: "^(gpmi_(io|apb|bch|bch_apb)|per1_bch)$" > > +- pattern: "^(gpmi_(io|apb|bch|bch_apb)|per1_bch)$" > > +- pattern: "^(gpmi_(io|apb|bch|bch_apb)|per1_bch)$" > > BTW, you can make 'items' a schema rather than a list to apply a > constraint to all entries: > > maxItems: 5 > items: > pattern: "^(gpmi_(io|apb|bch|bch_apb)|per1_bch)$" Right, I forgot about such syntax. > > > + > > + - if: > > + properties: > > +compatible: > > + contains: > > +const: fsl,imx7d-gpmi-nand > > +then: > > + properties: > > +clocks: > > + items: > > +- description: SoC gpmi io clock > > +- description: SoC gpmi bch apb clock > > +clock-names: > > + minItems: 2 > > + maxItems: 2 > > You can drop these. It's the default based on the size of 'items'. Sure. > > > + items: > > +- pattern: "^gpmi_(io|bch_apb)$" > > +- pattern: "^gpmi_(io|bch_apb)$" > > Surely here we can define the order. Yes, but still the same question as before - do we want the order? Why enforcing it? Best regards, Krzysztof
Re: [PATCH 14/20] usb/phy: mxs-usb: Use pm_ptr() macro
Paul Cercueil writes: > Use the newly introduced pm_ptr() macro, and mark the suspend/resume > functions __maybe_unused. These functions can then be moved outside the > CONFIG_PM_SUSPEND block, and the compiler can then process them and > detect build failures independently of the config. If unused, they will > simply be discarded by the compiler. > > Signed-off-by: Paul Cercueil > --- Acked-by: Felipe Balbi -- balbi signature.asc Description: PGP signature
[tip: core/build] arm/boot: Warn on orphan section placement
The following commit has been merged into the core/build branch of tip: Commit-ID: 4409d2f8dfe7d5088567d4ba00133f876ee586c7 Gitweb: https://git.kernel.org/tip/4409d2f8dfe7d5088567d4ba00133f876ee586c7 Author:Kees Cook AuthorDate:Tue, 01 Sep 2020 19:53:45 -07:00 Committer: Ingo Molnar CommitterDate: Thu, 03 Sep 2020 10:28:35 +02:00 arm/boot: Warn on orphan section placement We don't want to depend on the linker's orphan section placement heuristics as these can vary between linkers, and may change between versions. All sections need to be explicitly handled in the linker script. With all sections now handled, enable orphan section warning. Signed-off-by: Kees Cook Signed-off-by: Ingo Molnar Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20200902025347.2504702-4-keesc...@chromium.org --- arch/arm/boot/compressed/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index b1147b7..58028ab 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -123,6 +123,8 @@ endif LDFLAGS_vmlinux += --no-undefined # Delete all temporary local symbols LDFLAGS_vmlinux += -X +# Report orphan sections +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) # Next argument is a linker script LDFLAGS_vmlinux += -T
[tip: core/build] arm64/build: Warn on orphan section placement
The following commit has been merged into the core/build branch of tip: Commit-ID: b3e5d80d0c48c0cc7bce56473672f4e6e1210910 Gitweb: https://git.kernel.org/tip/b3e5d80d0c48c0cc7bce56473672f4e6e1210910 Author:Kees Cook AuthorDate:Tue, 01 Sep 2020 19:53:43 -07:00 Committer: Ingo Molnar CommitterDate: Thu, 03 Sep 2020 10:28:35 +02:00 arm64/build: Warn on orphan section placement We don't want to depend on the linker's orphan section placement heuristics as these can vary between linkers, and may change between versions. All sections need to be explicitly handled in the linker script. With all sections now handled, enable orphan section warnings. Signed-off-by: Kees Cook Signed-off-by: Ingo Molnar Acked-by: Will Deacon Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20200902025347.2504702-2-keesc...@chromium.org --- arch/arm64/Makefile | 4 1 file changed, 4 insertions(+) diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 6de7f55..081144f 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -29,6 +29,10 @@ LDFLAGS_vmlinux += --fix-cortex-a53-843419 endif endif +# We never want expected sections to be placed heuristically by the +# linker. All sections should be explicitly named in the linker script. +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) + ifeq ($(CONFIG_ARM64_USE_LSE_ATOMICS), y) ifneq ($(CONFIG_ARM64_LSE_ATOMICS), y) $(warning LSE atomics not supported by binutils)
[tip: core/build] x86/build: Warn on orphan section placement
The following commit has been merged into the core/build branch of tip: Commit-ID: 83109d5d5fba7abf362f5a443c9f4c4ea10bbc8d Gitweb: https://git.kernel.org/tip/83109d5d5fba7abf362f5a443c9f4c4ea10bbc8d Author:Kees Cook AuthorDate:Tue, 01 Sep 2020 19:53:46 -07:00 Committer: Ingo Molnar CommitterDate: Thu, 03 Sep 2020 10:28:36 +02:00 x86/build: Warn on orphan section placement We don't want to depend on the linker's orphan section placement heuristics as these can vary between linkers, and may change between versions. All sections need to be explicitly handled in the linker script. Now that all sections are explicitly handled, enable orphan section warnings. Signed-off-by: Kees Cook Signed-off-by: Ingo Molnar Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20200902025347.2504702-5-keesc...@chromium.org --- arch/x86/Makefile | 4 1 file changed, 4 insertions(+) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 4346ffb..154259f 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -209,6 +209,10 @@ ifdef CONFIG_X86_64 LDFLAGS_vmlinux += -z max-page-size=0x20 endif +# We never want expected sections to be placed heuristically by the +# linker. All sections should be explicitly named in the linker script. +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) + archscripts: scripts_basic $(Q)$(MAKE) $(build)=arch/x86/tools relocs
[tip: core/build] arm/build: Warn on orphan section placement
The following commit has been merged into the core/build branch of tip: Commit-ID: 5a17850e251a55bba6d65aefbfeacfa9888cd2cd Gitweb: https://git.kernel.org/tip/5a17850e251a55bba6d65aefbfeacfa9888cd2cd Author:Kees Cook AuthorDate:Tue, 01 Sep 2020 19:53:44 -07:00 Committer: Ingo Molnar CommitterDate: Thu, 03 Sep 2020 10:28:35 +02:00 arm/build: Warn on orphan section placement We don't want to depend on the linker's orphan section placement heuristics as these can vary between linkers, and may change between versions. All sections need to be explicitly handled in the linker script. Specifically, this would have made a recently fixed bug very obvious: ld: warning: orphan section `.fixup' from `arch/arm/lib/copy_from_user.o' being placed in section `.fixup' With all sections handled, enable orphan section warning. Signed-off-by: Kees Cook Signed-off-by: Ingo Molnar Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20200902025347.2504702-3-keesc...@chromium.org --- arch/arm/Makefile | 4 1 file changed, 4 insertions(+) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4e87735..e589da3 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -16,6 +16,10 @@ LDFLAGS_vmlinux += --be8 KBUILD_LDFLAGS_MODULE += --be8 endif +# We never want expected sections to be placed heuristically by the +# linker. All sections should be explicitly named in the linker script. +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) + ifeq ($(CONFIG_ARM_MODULE_PLTS),y) KBUILD_LDS_MODULE += $(srctree)/arch/arm/kernel/module.lds endif
[tip: core/build] x86/boot/compressed: Warn on orphan section placement
The following commit has been merged into the core/build branch of tip: Commit-ID: 6e0bf0e0e55000742a53c5f3b58f8669e0091a11 Gitweb: https://git.kernel.org/tip/6e0bf0e0e55000742a53c5f3b58f8669e0091a11 Author:Kees Cook AuthorDate:Tue, 01 Sep 2020 19:53:47 -07:00 Committer: Ingo Molnar CommitterDate: Thu, 03 Sep 2020 10:28:36 +02:00 x86/boot/compressed: Warn on orphan section placement We don't want to depend on the linker's orphan section placement heuristics as these can vary between linkers, and may change between versions. All sections need to be explicitly handled in the linker script. Now that all sections are explicitly handled, enable orphan section warnings. Signed-off-by: Kees Cook Signed-off-by: Ingo Molnar Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20200902025347.2504702-6-keesc...@chromium.org --- arch/x86/boot/compressed/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 5b7f6e1..871cc07 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -54,6 +54,7 @@ KBUILD_LDFLAGS += $(call ld-option,--no-ld-generated-unwind-info) # Compressed kernel should be built as PIE since it may be loaded at any # address by the bootloader. LDFLAGS_vmlinux := -pie $(call ld-option, --no-dynamic-linker) +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) LDFLAGS_vmlinux += -T hostprogs := mkpiggy
Re: remove set_fs for riscv
On Mon, Sep 07, 2020 at 12:14:59AM +0200, Arnd Bergmann wrote: > I've had a first pass at this now, see > > https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=arm-kill-set_fs > > There are a couple of things in there that ended up uglier than I was > hoping for, and it's completely untested beyond compilation. Is this > roughly what you had in mind? I can do some testing then and post > it to the Arm mailing list. Looks sensible. The OABI hacks a are a little ugly, but so would be every other alternative. Note that you don't need to add a TASK_SIZE_MAX definition to arm if you base it on my series as that provides a default one. I also think with these changes arm/nommu should be able to use UACCESS_MEMCPY.
[PATCH 7/8] riscv: implement __get_kernel_nofault and __put_user_nofault
Implement the non-faulting kernel access helpers directly instead of abusing the uaccess routines under set_fs(KERNEL_DS). Signed-off-by: Christoph Hellwig --- arch/riscv/include/asm/uaccess.h | 20 1 file changed, 20 insertions(+) diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index b67d1c616ec348..264e52fb62b143 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -486,6 +486,26 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n) __ret; \ }) +#define HAVE_GET_KERNEL_NOFAULT + +#define __get_kernel_nofault(dst, src, type, err_label) \ +do { \ + long __kr_err; \ + \ + __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ + if (unlikely(__kr_err)) \ + goto err_label; \ +} while (0) + +#define __put_kernel_nofault(dst, src, type, err_label) \ +do { \ + long __kr_err; \ + \ + __put_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ + if (unlikely(__kr_err)) \ + goto err_label; \ +} while (0) + #else /* CONFIG_MMU */ #include #endif /* CONFIG_MMU */ -- 2.28.0
[PATCH 3/8] asm-generic: add nommu implementations of __{get,put}_kernel_nofault
Add native implementations of __{get,put}_kernel_nofault using {get,put}_unaligned, just like the {get,put}_user implementations. Signed-off-by: Christoph Hellwig --- include/asm-generic/uaccess.h | 16 1 file changed, 16 insertions(+) diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index 6de5f524e9e631..b367f339be1a90 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -61,6 +61,22 @@ static inline int __put_user_fn(size_t size, void __user *to, void *from) } #define __put_user_fn(sz, u, k)__put_user_fn(sz, u, k) +#define __get_kernel_nofault(dst, src, type, err_label) \ +do { \ + *((type *)dst) = get_unaligned((type *)(src)); \ + if (0) /* make sure the label looks used to the compiler */ \ + goto err_label; \ +} while (0) + +#define __put_kernel_nofault(dst, src, type, err_label) \ +do { \ + put_unaligned(*((type *)src), (type *)(dst)); \ + if (0) /* make sure the label looks used to the compiler */ \ + goto err_label; \ +} while (0) + +#define HAVE_GET_KERNEL_NOFAULT 1 + static inline __must_check unsigned long raw_copy_from_user(void *to, const void __user * from, unsigned long n) { -- 2.28.0
[PATCH 5/8] riscv: use memcpy based uaccess for nommu again
This reverts commit adccfb1a805ea84d2db38eb53032533279bdaa97. Now that the generic uaccess by mempcy code handles unaligned addresses the generic code can be used for all RISC-V CPUs. Signed-off-by: Christoph Hellwig --- arch/riscv/Kconfig | 1 + arch/riscv/include/asm/uaccess.h | 36 arch/riscv/lib/Makefile | 2 +- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 07d53044013ede..460e3971a80fde 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -87,6 +87,7 @@ config RISCV select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK select SET_FS + select UACCESS_MEMCPY if !MMU config ARCH_MMAP_RND_BITS_MIN default 18 if 64BIT diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index f56c66b3f5fe21..e8eedf22e90747 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -13,24 +13,6 @@ /* * User space memory access functions */ - -extern unsigned long __must_check __asm_copy_to_user(void __user *to, - const void *from, unsigned long n); -extern unsigned long __must_check __asm_copy_from_user(void *to, - const void __user *from, unsigned long n); - -static inline unsigned long -raw_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - return __asm_copy_from_user(to, from, n); -} - -static inline unsigned long -raw_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - return __asm_copy_to_user(to, from, n); -} - #ifdef CONFIG_MMU #include #include @@ -385,6 +367,24 @@ do { \ -EFAULT;\ }) + +unsigned long __must_check __asm_copy_to_user(void __user *to, + const void *from, unsigned long n); +unsigned long __must_check __asm_copy_from_user(void *to, + const void __user *from, unsigned long n); + +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + return __asm_copy_from_user(to, from, n); +} + +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + return __asm_copy_to_user(to, from, n); +} + extern long strncpy_from_user(char *dest, const char __user *src, long count); extern long __must_check strlen_user(const char __user *str); diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 0d0db80800c4ed..47e7a82044608d 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -2,5 +2,5 @@ lib-y += delay.o lib-y += memcpy.o lib-y += memset.o -lib-y += uaccess.o +lib-$(CONFIG_MMU) += uaccess.o lib-$(CONFIG_64BIT)+= tishift.o -- 2.28.0
[PATCH 8/8] riscv: remove address space overrides using set_fs()
Stop providing the possibility to override the address space using set_fs() now that there is no need for that any more. Signed-off-by: Christoph Hellwig --- arch/riscv/Kconfig | 1 - arch/riscv/include/asm/thread_info.h | 6 -- arch/riscv/include/asm/uaccess.h | 27 +-- arch/riscv/kernel/process.c | 1 - 4 files changed, 1 insertion(+), 34 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 460e3971a80fde..33dde87218ddab 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -86,7 +86,6 @@ config RISCV select SPARSE_IRQ select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK - select SET_FS select UACCESS_MEMCPY if !MMU config ARCH_MMAP_RND_BITS_MIN diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h index 464a2bbc97ea33..a390711129de64 100644 --- a/arch/riscv/include/asm/thread_info.h +++ b/arch/riscv/include/asm/thread_info.h @@ -24,10 +24,6 @@ #include #include -typedef struct { - unsigned long seg; -} mm_segment_t; - /* * low level task data that entry.S needs immediate access to * - this struct should fit entirely inside of one cache line @@ -39,7 +35,6 @@ typedef struct { struct thread_info { unsigned long flags; /* low level flags */ int preempt_count; /* 0=>preemptible, <0=>BUG */ - mm_segment_taddr_limit; /* * These stack pointers are overwritten on every system call or * exception. SP is also saved to the stack it can be recovered when @@ -59,7 +54,6 @@ struct thread_info { { \ .flags = 0,\ .preempt_count = INIT_PREEMPT_COUNT, \ - .addr_limit = KERNEL_DS,\ } #endif /* !__ASSEMBLY__ */ diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index 264e52fb62b143..c47e6b35c551f4 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -26,29 +26,6 @@ #define __disable_user_access() \ __asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory") -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons, these macros are grossly misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(~0UL) -#define USER_DSMAKE_MM_SEG(TASK_SIZE) - -#define get_fs() (current_thread_info()->addr_limit) - -static inline void set_fs(mm_segment_t fs) -{ - current_thread_info()->addr_limit = fs; -} - -#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) -#define user_addr_max()(get_fs().seg) - /** * access_ok: - Checks if a user space pointer is valid * @addr: User space pointer to start of block to check @@ -76,9 +53,7 @@ static inline void set_fs(mm_segment_t fs) */ static inline int __access_ok(unsigned long addr, unsigned long size) { - const mm_segment_t fs = get_fs(); - - return size <= fs.seg && addr <= fs.seg - size; + return size <= TASK_SIZE && addr <= TASK_SIZE - size; } /* diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 2b97c493427c9e..19225ec65db62f 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -84,7 +84,6 @@ void start_thread(struct pt_regs *regs, unsigned long pc, } regs->epc = pc; regs->sp = sp; - set_fs(USER_DS); } void flush_thread(void) -- 2.28.0
remove set_fs for riscv v2
Hi all, this series converts riscv to the new set_fs less world and is on top of this branch: https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git/log/?h=base.set_fs The first four patches are general improvements and enablement for all nommu ports, and might make sense to merge through the above base branch. Changes since v1: - implement __get_user_fn and __put_user_fn for the UACCESS_MEMCPY case and remove the small constant size optimizations in raw_copy_from_user and raw_copy_to_user - reshuffle the patch order a little Diffstat arch/riscv/Kconfig |2 arch/riscv/include/asm/thread_info.h |6 - arch/riscv/include/asm/uaccess.h | 177 +-- arch/riscv/kernel/process.c |1 arch/riscv/lib/Makefile |2 include/asm-generic/uaccess.h| 109 + include/linux/uaccess.h |4 7 files changed, 166 insertions(+), 135 deletions(-)
[PATCH 6/8] riscv: refactor __get_user and __put_user
Add new __get_user_nocheck and __put_user_nocheck that switch on the size and call the actual inline assembly helpers, and move the uaccess enable / disable into the actual __get_user and __put_user. This prepares for natively implementing __get_kernel_nofault and __put_kernel_nofault. Also don't bother with the deprecated register keyword for the error return. Signed-off-by: Christoph Hellwig --- arch/riscv/include/asm/uaccess.h | 94 ++-- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index e8eedf22e90747..b67d1c616ec348 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -107,7 +107,6 @@ static inline int __access_ok(unsigned long addr, unsigned long size) do { \ uintptr_t __tmp;\ __typeof__(x) __x; \ - __enable_user_access(); \ __asm__ __volatile__ ( \ "1:\n" \ " " insn " %1, %3\n" \ @@ -125,7 +124,6 @@ do { \ " .previous" \ : "+r" (err), "=&r" (__x), "=r" (__tmp) \ : "m" (*(ptr)), "i" (-EFAULT)); \ - __disable_user_access();\ (x) = __x; \ } while (0) @@ -138,7 +136,6 @@ do { \ u32 __user *__ptr = (u32 __user *)(ptr);\ u32 __lo, __hi; \ uintptr_t __tmp;\ - __enable_user_access(); \ __asm__ __volatile__ ( \ "1:\n" \ " lw %1, %4\n"\ @@ -162,12 +159,30 @@ do { \ "=r" (__tmp)\ : "m" (__ptr[__LSW]), "m" (__ptr[__MSW]), \ "i" (-EFAULT)); \ - __disable_user_access();\ (x) = (__typeof__(x))((__typeof__((x)-(x)))(\ (((u64)__hi << 32) | __lo))); \ } while (0) #endif /* CONFIG_64BIT */ +#define __get_user_nocheck(x, __gu_ptr, __gu_err) \ +do { \ + switch (sizeof(*__gu_ptr)) {\ + case 1: \ + __get_user_asm("lb", (x), __gu_ptr, __gu_err); \ + break; \ + case 2: \ + __get_user_asm("lh", (x), __gu_ptr, __gu_err); \ + break; \ + case 4: \ + __get_user_asm("lw", (x), __gu_ptr, __gu_err); \ + break; \ + case 8: \ + __get_user_8((x), __gu_ptr, __gu_err); \ + break; \ + default:\ + BUILD_BUG();\ + } \ +} while (0) /** * __get_user: - Get a simple variable from user space, with less checking. @@ -191,25 +206,15 @@ do { \ */ #define __get_user(x, ptr) \ ({ \ - register long __gu_err = 0; \ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ + long __gu_err = 0; \ + \ __chk_user_ptr(__gu_ptr); \ - switch (sizeof(*__gu_ptr)) {\ - case 1: \ - __get_user_asm("lb", (x), __gu_ptr, __gu_err); \ - break; \ - case 2: \ - __get_user_asm(
[PATCH 4/8] asm-generic: make the set_fs implementation optional
Put all the set_fs related code under CONFIG_SET_FS so that asm-generic/uaccess.h can be used for set_fs-less builds. Signed-off-by: Christoph Hellwig --- include/asm-generic/uaccess.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index b367f339be1a90..45f9872fd74759 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -94,6 +94,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n) #define INLINE_COPY_TO_USER #endif /* CONFIG_UACCESS_MEMCPY */ +#ifdef CONFIG_SET_FS #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) #ifndef KERNEL_DS @@ -116,6 +117,7 @@ static inline void set_fs(mm_segment_t fs) #ifndef uaccess_kernel #define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) #endif +#endif /* CONFIG_SET_FS */ #define access_ok(addr, size) __access_ok((unsigned long)(addr),(size)) -- 2.28.0
[PATCH 1/8] uaccess: provide a generic TASK_SIZE_MAX definition
Define TASK_SIZE_MAX as TASK_SIZE if not otherwise defined. Signed-off-by: Christoph Hellwig --- include/linux/uaccess.h | 4 1 file changed, 4 insertions(+) diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 70073c802b48ed..d0e43761c708d8 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -31,6 +31,10 @@ typedef struct { /* empty dummy */ } mm_segment_t; +#ifndef TASK_SIZE_MAX +#define TASK_SIZE_MAX TASK_SIZE +#endif + #define uaccess_kernel() (false) #define user_addr_max()(TASK_SIZE_MAX) -- 2.28.0
[PATCH 2/8] asm-generic: improve the nommu {get,put}_user handling
Instead of reusing raw_{copy,to}_from_user implement separate handlers using {get,put}_unaligned. This ensures unaligned access is handled correctly, and avoid the need for the small constant size optimization in raw_{copy,to}_from_user. Signed-off-by: Christoph Hellwig --- include/asm-generic/uaccess.h | 91 --- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index ba68ee4dabfaa7..6de5f524e9e631 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -10,28 +10,60 @@ #include #ifdef CONFIG_UACCESS_MEMCPY -static inline __must_check unsigned long -raw_copy_from_user(void *to, const void __user * from, unsigned long n) +#include + +static inline int __get_user_fn(size_t size, const void __user *from, void *to) { - if (__builtin_constant_p(n)) { - switch(n) { - case 1: - *(u8 *)to = *(u8 __force *)from; - return 0; - case 2: - *(u16 *)to = *(u16 __force *)from; - return 0; - case 4: - *(u32 *)to = *(u32 __force *)from; - return 0; -#ifdef CONFIG_64BIT - case 8: - *(u64 *)to = *(u64 __force *)from; - return 0; -#endif - } + BUILD_BUG_ON(!__builtin_constant_p(size)); + + switch (size) { + case 1: + *(u8 *)to = get_unaligned((u8 __force *)from); + return 0; + case 2: + *(u16 *)to = get_unaligned((u16 __force *)from); + return 0; + case 4: + *(u32 *)to = get_unaligned((u32 __force *)from); + return 0; + case 8: + *(u64 *)to = get_unaligned((u64 __force *)from); + return 0; + default: + BUILD_BUG(); + return 0; + } + +} +#define __get_user_fn(sz, u, k)__get_user_fn(sz, u, k) + +static inline int __put_user_fn(size_t size, void __user *to, void *from) +{ + BUILD_BUG_ON(!__builtin_constant_p(size)); + + switch (size) { + case 1: + put_unaligned(*(u8 *)from, (u8 __force *)to); + return 0; + case 2: + put_unaligned(*(u16 *)from, (u16 __force *)to); + return 0; + case 4: + put_unaligned(*(u32 *)from, (u32 __force *)to); + return 0; + case 8: + put_unaligned(*(u64 *)from, (u64 __force *)to); + return 0; + default: + BUILD_BUG(); + return 0; } +} +#define __put_user_fn(sz, u, k)__put_user_fn(sz, u, k) +static inline __must_check unsigned long +raw_copy_from_user(void *to, const void __user * from, unsigned long n) +{ memcpy(to, (const void __force *)from, n); return 0; } @@ -39,27 +71,6 @@ raw_copy_from_user(void *to, const void __user * from, unsigned long n) static inline __must_check unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (__builtin_constant_p(n)) { - switch(n) { - case 1: - *(u8 __force *)to = *(u8 *)from; - return 0; - case 2: - *(u16 __force *)to = *(u16 *)from; - return 0; - case 4: - *(u32 __force *)to = *(u32 *)from; - return 0; -#ifdef CONFIG_64BIT - case 8: - *(u64 __force *)to = *(u64 *)from; - return 0; -#endif - default: - break; - } - } - memcpy((void __force *)to, from, n); return 0; } -- 2.28.0
Re: [PATCH v2 2/3] soc: sifive: Add SiFive specific Cadence DDR controller driver
On 9/6/20 10:47 PM, Yash Shah wrote: > diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig > index 58cf8c4..f41d8fe 100644 > --- a/drivers/soc/sifive/Kconfig > +++ b/drivers/soc/sifive/Kconfig > @@ -7,4 +7,10 @@ config SIFIVE_L2 > help > Support for the L2 cache controller on SiFive platforms. > > +config SIFIVE_DDR > + bool "Sifive DDR controller driver" > + help > + Support for the management of cadence DDR controller on SiFive Cadence > + platforms. > + > endif -- ~Randy
[PATCH v2 1/3] dt-bindings: riscv: Add DT documentation for DDR Controller in SiFive SoCs
Add device tree bindings for SiFive FU540 DDR controller driver Signed-off-by: Yash Shah Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt --- .../devicetree/bindings/riscv/sifive-ddr.yaml | 41 ++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/sifive-ddr.yaml diff --git a/Documentation/devicetree/bindings/riscv/sifive-ddr.yaml b/Documentation/devicetree/bindings/riscv/sifive-ddr.yaml new file mode 100644 index 000..0288119 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/sifive-ddr.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/riscv/sifive-ddr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SiFive DDR memory controller binding + +description: | + The Sifive DDR controller driver is used to manage the Cadence DDR + controller present in SiFive FU540-C000 SoC. Currently the driver is + used to manage EDAC feature of the DDR controller. + +maintainers: + - Yash Shah + +properties: + compatible: +enum: + - sifive,fu540-c000-ddr + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | +memory-controller@100b { +compatible = "sifive,fu540-c000-ddr"; +reg = <0x100b 0x4000>; +interrupts = <31>; +}; -- 2.7.4
[PATCH v2 0/3] SiFive DDR controller and EDAC support
The series add supports for SiFive DDR controller driver. This driver is use to manage the Cadence DDR controller present in SiFive SoCs. Currently it manages only the EDAC feature of the DDR controller. The series also adds Memory controller EDAC support for SiFive platform. It register for notifier event from SiFive DDR controller driver. The series is tested and based on Linux v5.8. For testing on Hifive Unleashed: 1. Enable the ECC bit of DDR controller during DDR initialization 2. Erase the entire DRAM in bootloader stage 3. Using FWC feature of DDR controller force ecc error to test Changes in v2: Incorporate below changes in EDAC patch as suggested by Borislav Petkov - Replace all ifdeffery with if(IS_ENABLED(CONFIG_...)) - A few textual changes in patch description and code Yash Shah (3): dt-bindings: riscv: Add DT documentation for DDR Controller in SiFive SoCs soc: sifive: Add SiFive specific Cadence DDR controller driver EDAC/sifive: Add EDAC support for Memory Controller in SiFive SoCs .../devicetree/bindings/riscv/sifive-ddr.yaml | 41 drivers/edac/Kconfig | 2 +- drivers/edac/sifive_edac.c | 119 +++- drivers/soc/sifive/Kconfig | 6 + drivers/soc/sifive/Makefile| 3 +- drivers/soc/sifive/sifive_ddr.c| 207 + include/soc/sifive/sifive_ddr.h| 73 7 files changed, 447 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/riscv/sifive-ddr.yaml create mode 100644 drivers/soc/sifive/sifive_ddr.c create mode 100644 include/soc/sifive/sifive_ddr.h -- 2.7.4
[PATCH v2 3/3] EDAC/sifive: Add EDAC support for Memory Controller in SiFive SoCs
Add Memory controller EDAC support to the SiFive platform EDAC driver. It registers for ECC notifier events from the memory controller. Signed-off-by: Yash Shah Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt --- drivers/edac/Kconfig | 2 +- drivers/edac/sifive_edac.c | 119 - 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 7b6ec30..f8b3b53 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -462,7 +462,7 @@ config EDAC_ALTERA_SDMMC config EDAC_SIFIVE bool "Sifive platform EDAC driver" - depends on EDAC=y && SIFIVE_L2 + depends on EDAC=y && (SIFIVE_L2 || SIFIVE_DDR) help Support for error detection and correction on the SiFive SoCs. diff --git a/drivers/edac/sifive_edac.c b/drivers/edac/sifive_edac.c index 3a3dcb1..17dd556 100644 --- a/drivers/edac/sifive_edac.c +++ b/drivers/edac/sifive_edac.c @@ -11,14 +11,119 @@ #include #include "edac_module.h" #include +#include #define DRVNAME "sifive_edac" +#define EDAC_MOD_NAME "Sifive ECC Manager" struct sifive_edac_priv { struct notifier_block notifier; struct edac_device_ctl_info *dci; }; +struct sifive_edac_mc_priv { + struct notifier_block notifier; + struct mem_ctl_info *mci; +}; + +/** + * EDAC MC error callback + * + * @event: non-zero if unrecoverable. + */ +static +int ecc_mc_err_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct sifive_ddr_priv *priv = ptr; + struct sifive_edac_mc_priv *p; + + p = container_of(this, struct sifive_edac_mc_priv, notifier); + if (event == SIFIVE_DDR_ERR_TYPE_UE) { + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, p->mci, +priv->error_count, priv->page_frame_number, +priv->offset_in_page, priv->syndrome, +priv->top_layer, priv->mid_layer, +priv->low_layer, p->mci->ctl_name, ""); + } else if (event == SIFIVE_DDR_ERR_TYPE_CE) { + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, p->mci, +priv->error_count, priv->page_frame_number, +priv->offset_in_page, priv->syndrome, +priv->top_layer, priv->mid_layer, +priv->low_layer, p->mci->ctl_name, ""); + } + + return NOTIFY_OK; +} + +static int ecc_mc_register(struct platform_device *pdev) +{ + struct sifive_edac_mc_priv *p; + struct edac_mc_layer layers[1]; + int ret; + + p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->notifier.notifier_call = ecc_mc_err_event; + platform_set_drvdata(pdev, p); + + layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; + layers[0].size = 1; + layers[0].is_virt_csrow = true; + + p->mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0); + if (!p->mci) { + dev_err(&pdev->dev, "Failed mem allocation for mc instance\n"); + return -ENOMEM; + } + + p->mci->pdev = &pdev->dev; + /* Initialize controller capabilities */ + p->mci->mtype_cap = MEM_FLAG_DDR4; + p->mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; + p->mci->edac_cap = EDAC_FLAG_SECDED; + p->mci->scrub_cap = SCRUB_UNKNOWN; + p->mci->scrub_mode = SCRUB_HW_PROG; + p->mci->ctl_name = dev_name(&pdev->dev); + p->mci->dev_name = dev_name(&pdev->dev); + p->mci->mod_name = EDAC_MOD_NAME; + p->mci->ctl_page_to_phys = NULL; + + /* Interrupt feature is supported by cadence mc */ + edac_op_state = EDAC_OPSTATE_INT; + + ret = edac_mc_add_mc(p->mci); + if (ret) { + edac_printk(KERN_ERR, EDAC_MOD_NAME, + "Failed to register with EDAC core\n"); + goto err; + } + + if (IS_ENABLED(CONFIG_SIFIVE_DDR)) + register_sifive_ddr_error_notifier(&p->notifier); + + return 0; + +err: + edac_mc_free(p->mci); + + return -ENXIO; +} + +static int ecc_mc_unregister(struct platform_device *pdev) +{ + struct sifive_edac_mc_priv *p = platform_get_drvdata(pdev); + + if (IS_ENABLED(CONFIG_SIFIVE_DDR)) + unregister_sifive_ddr_error_notifier(&p->notifier); + + edac_mc_del_mc(&pdev->dev); + edac_mc_free(p->mci); + + return 0; +} + /** * EDAC error callback * @@ -67,7 +172,8 @@ static int ecc_register(struct platform_device *pdev) goto err; } - register_sifive_l2_error_notifier(&p->notifier); + if (IS_ENABLED(CONFIG_SIFIVE_L2)) + register_sifive_l2_error_notifier(&p->notifier); return 0; @@ -81,7 +1
[PATCH v2 2/3] soc: sifive: Add SiFive specific Cadence DDR controller driver
Add a driver to manage the Cadence DDR controller present on SiFive SoCs At present the driver manages the EDAC feature of the DDR controller. Additional features may be added to the driver in future to control other aspects of the DDR controller. Signed-off-by: Yash Shah Reviewed-by: Palmer Dabbelt Acked-by: Palmer Dabbelt --- drivers/soc/sifive/Kconfig | 6 ++ drivers/soc/sifive/Makefile | 3 +- drivers/soc/sifive/sifive_ddr.c | 207 include/soc/sifive/sifive_ddr.h | 73 ++ 4 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/sifive/sifive_ddr.c create mode 100644 include/soc/sifive/sifive_ddr.h diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig index 58cf8c4..f41d8fe 100644 --- a/drivers/soc/sifive/Kconfig +++ b/drivers/soc/sifive/Kconfig @@ -7,4 +7,10 @@ config SIFIVE_L2 help Support for the L2 cache controller on SiFive platforms. +config SIFIVE_DDR + bool "Sifive DDR controller driver" + help + Support for the management of cadence DDR controller on SiFive + platforms. + endif diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile index b5caff7..b4acb5c 100644 --- a/drivers/soc/sifive/Makefile +++ b/drivers/soc/sifive/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_SIFIVE_L2)+= sifive_l2_cache.o +obj-$(CONFIG_SIFIVE_L2)+= sifive_l2_cache.o +obj-$(CONFIG_SIFIVE_DDR) += sifive_ddr.o diff --git a/drivers/soc/sifive/sifive_ddr.c b/drivers/soc/sifive/sifive_ddr.c new file mode 100644 index 000..b1b421c --- /dev/null +++ b/drivers/soc/sifive/sifive_ddr.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SiFive specific cadence DDR controller Driver + * + * Copyright (C) 2019-2020 SiFive, Inc. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static ATOMIC_NOTIFIER_HEAD(ddr_err_chain); + +int register_sifive_ddr_error_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&ddr_err_chain, nb); +} +EXPORT_SYMBOL_GPL(register_sifive_ddr_error_notifier); + +int unregister_sifive_ddr_error_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&ddr_err_chain, nb); +} +EXPORT_SYMBOL_GPL(unregister_sifive_ddr_error_notifier); + +static void handle_ce(struct sifive_ddr_priv *pv) +{ + u64 err_c_addr = 0x0; + u64 err_c_data = 0x0; + u32 err_c_synd, err_c_id; + u32 sig_val_l, sig_val_h; + + sig_val_l = readl(pv->reg + ECC_C_ADDR_L_REG); + sig_val_h = (readl(pv->reg + ECC_C_ADDR_H_REG) & +ECC_ADDR_H_MASK); + err_c_addr = (((ulong)sig_val_h << CTL_REG_WIDTH_SHIFT) | sig_val_l); + + sig_val_l = readl(pv->reg + ECC_C_DATA_L_REG); + sig_val_h = readl(pv->reg + ECC_C_DATA_H_REG); + err_c_data = (((ulong)sig_val_h << CTL_REG_WIDTH_SHIFT) | sig_val_l); + + err_c_id = ((readl(pv->reg + ECC_U_C_ID_REG) & +ECC_C_ID_MASK) >> ECC_C_ID_SHIFT); + + err_c_synd = ((readl(pv->reg + ECC_C_SYND_REG) & + ECC_SYND_MASK) >> ECC_SYND_SHIFT); + + pv->error_count = 1; + pv->page_frame_number = err_c_addr >> PAGE_SHIFT; + pv->offset_in_page = err_c_addr & ~PAGE_MASK; + pv->syndrome = err_c_synd; + pv->top_layer = 0; + pv->mid_layer = 0; + pv->low_layer = -1; + + atomic_notifier_call_chain(&ddr_err_chain, SIFIVE_DDR_ERR_TYPE_CE, pv); +} + +static void handle_ue(struct sifive_ddr_priv *pv) +{ + u64 err_u_addr = 0x0; + u64 err_u_data = 0x0; + u32 err_u_synd, err_u_id; + u32 sig_val_l, sig_val_h; + + sig_val_l = readl(pv->reg + ECC_U_ADDR_L_REG); + sig_val_h = (readl(pv->reg + ECC_U_ADDR_H_REG) & +ECC_ADDR_H_MASK); + err_u_addr = (((ulong)sig_val_h << CTL_REG_WIDTH_SHIFT) | sig_val_l); + + sig_val_l = readl(pv->reg + ECC_U_DATA_L_REG); + sig_val_h = readl(pv->reg + ECC_U_DATA_H_REG); + err_u_data = (((ulong)sig_val_h << CTL_REG_WIDTH_SHIFT) | sig_val_l); + + err_u_id = ((readl(pv->reg + ECC_U_C_ID_REG) & + ECC_U_ID_MASK) >> ECC_U_ID_SHIFT); + + err_u_synd = ((readl(pv->reg + ECC_U_SYND_REG) & + ECC_SYND_MASK) >> ECC_SYND_SHIFT); + + pv->error_count = 1; + pv->page_frame_number = err_u_addr >> PAGE_SHIFT; + pv->offset_in_page = err_u_addr & ~PAGE_MASK; + pv->syndrome = err_u_synd; + pv->top_layer = 0; + pv->mid_layer = 0; + pv->low_layer = -1; + + atomic_notifier_call_chain(&ddr_err_chain, SIFIVE_DDR_ERR_TYPE_UE, pv); +} + +static irqreturn_t ecc_isr(int irq, void *ptr) +{ + struct sifive_ddr_priv *pv = ptr; + u32 intr_status; + u32 val; + + /* Check the intr status and confirm ECC error intr */ +
Re: [PATCH V2] sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output
On Sun, Sep 06, 2020 at 10:24:20AM -0700, Joe Perches wrote: > On Sat, 2020-08-29 at 16:48 -0700, Joe Perches wrote: > > Output defects can exist in sysfs content using sprintf and snprintf. > > > > sprintf does not know the PAGE_SIZE maximum of the temporary buffer > > used for outputting sysfs content and it's possible to overrun the > > PAGE_SIZE buffer length. > > > > Add a generic sysfs_emit function that knows that the size of the > > temporary buffer and ensures that no overrun is done. > > > > Add a generic sysfs_emit_at function that can be used in multiple > > call situations that also ensures that no overrun is done. > > > > Signed-off-by: Joe Perches > > --- > > > > V2: Simplify sysfs_emit and add sysfs_emit_at > > Include Documentation change > > Greg? Rafael? Thoughts on this? I like the idea, give me a chance to catch up on patches, it's still in my to-review queue... thanks, greg k-h
Re: [Linux-kernel-mentees] [PATCH] block : Fix use-after-free Read in delete_partition
On Mon, Sep 07, 2020 at 01:41:56AM +0530, Anant Thazhemadam wrote: > A use-after-free read of the kobject member being casted out to the > device structure containing it seems to be potentially possible > due to unsafe casting using container_of (since an edge case such > as when the ptr being casted might be NULL or problematic is not > accounted for). > Using container_of_safe resolves this issue, with no obvious tradeoffs > and without considerable expense. No, now every caller has to check for NULL, and that would mean that you now need to fix up hundreds of different places in the kernel. Please fix the root cause that would cause NULL to be passed to this call in the block code, don't paper over the issue here. thanks, greg k-h
[PATCH 5/7] dt-bindings: pci: layerscape-pci: Update the description of SCFG property
From: Hou Zhiqiang Update the description of the second entry of 'fsl,pcie-scfg' property, as the LS1043A PCIe controller also has some control registers in SCFG block, while it has 3 controllers. Signed-off-by: Hou Zhiqiang --- Documentation/devicetree/bindings/pci/layerscape-pci.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index 2236d3f3089b..e992ec712bf6 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -31,7 +31,7 @@ Required properties: "intr": The interrupt that is asserted for controller interrupts - fsl,pcie-scfg: Must include two entries. The first entry must be a link to the SCFG device node - The second entry must be '0' or '1' based on physical PCIe controller index. + The second entry is the physical PCIe controller index starting from '0'. This is used to get SCFG PEXN registers - dma-coherent: Indicates that the hardware IP block can ensure the coherency of the data transferred from/to the IP block. This can avoid the software -- 2.17.1
[PATCH 6/7] dts: arm64: ls1043a: Add SCFG phandle for PCIe nodes
From: Hou Zhiqiang The LS1043A PCIe controller has some control registers in SCFG block, so add the SCFG phandle for each PCIe controller DT node. Signed-off-by: Hou Zhiqiang --- arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 70e07612da12..30ccf1fdb851 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -822,6 +822,7 @@ interrupts = <0 118 0x4>, /* controller interrupt */ <0 117 0x4>; /* PME interrupt */ interrupt-names = "intr", "pme"; + fsl,pcie-scfg = <&scfg 0>; #address-cells = <3>; #size-cells = <2>; device_type = "pci"; @@ -849,6 +850,7 @@ interrupts = <0 128 0x4>, <0 127 0x4>; interrupt-names = "intr", "pme"; + fsl,pcie-scfg = <&scfg 1>; #address-cells = <3>; #size-cells = <2>; device_type = "pci"; @@ -876,6 +878,7 @@ interrupts = <0 162 0x4>, <0 161 0x4>; interrupt-names = "intr", "pme"; + fsl,pcie-scfg = <&scfg 2>; #address-cells = <3>; #size-cells = <2>; device_type = "pci"; -- 2.17.1
[PATCH 7/7] PCI: layerscape: Add power management support
From: Hou Zhiqiang Add PME_Turn_Off/PME_TO_Ack handshake sequence, and finally put the PCIe controller into D3 state after the L2/L3 ready state transition process completion. Signed-off-by: Hou Zhiqiang --- drivers/pci/controller/dwc/pci-layerscape.c | 384 ++- drivers/pci/controller/dwc/pcie-designware.h | 1 + 2 files changed, 383 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c index be404c16bcbe..ca9ea07f77c1 100644 --- a/drivers/pci/controller/dwc/pci-layerscape.c +++ b/drivers/pci/controller/dwc/pci-layerscape.c @@ -3,13 +3,16 @@ * PCIe host controller driver for Freescale Layerscape SoCs * * Copyright (C) 2014 Freescale Semiconductor. + * Copyright 2020 NXP * * Author: Minghuan Lian */ +#include #include #include #include +#include #include #include #include @@ -27,17 +30,66 @@ #define PCIE_ABSERR0x8d0 /* Bridge Slave Error Response Register */ #define PCIE_ABSERR_SETTING0x9401 /* Forward error of non-posted request */ +#define PCIE_PM_SCR0x44 +#define PCIE_PM_SCR_PMEPS_D0 0x0 +#define PCIE_PM_SCR_PMEPS_D3 0x3 + +#define PCIE_LNKCTL0x80 /* PCIe link ctrl Register */ + +/* PF Message Command Register */ +#define LS_PCIE_PF_MCR 0x2c +#define PF_MCR_PTOMR BIT(0) +#define PF_MCR_EXL2S BIT(1) + +/* LS1021A PEXn PM Write Control Register */ +#define SCFG_PEXPMWRCR(idx)(0x5c + (idx) * 0x64) +#define PMXMTTURNOFF BIT(31) +#define SCFG_PEXSFTRSTCR 0x190 +#define PEXSR(idx) BIT(idx) + +/* LS1043A PEX PME control register */ +#define SCFG_PEXPMECR 0x144 +#define PEXPME(idx)BIT(31 - (idx) * 4) + +/* LS1043A PEX LUT debug register */ +#define LS_PCIE_LDBG 0x7fc +#define LDBG_SRBIT(30) +#define LDBG_WEBIT(31) + #define PCIE_IATU_NUM 6 +#define LS_PCIE_IS_L2(v) \ + (((v) & PORT_LOGIC_LTSSM_STATE_MASK) == PORT_LOGIC_LTSSM_STATE_L2) + +struct ls_pcie; + +struct ls_pcie_host_pm_ops { + int (*pm_init)(struct ls_pcie *pcie); + void (*send_turn_off_message)(struct ls_pcie *pcie); + void (*exit_from_l2)(struct ls_pcie *pcie); +}; + struct ls_pcie_drvdata { + const u32 pf_off; + const u32 lut_off; const struct dw_pcie_host_ops *ops; + const struct ls_pcie_host_pm_ops *pm_ops; }; struct ls_pcie { struct dw_pcie *pci; const struct ls_pcie_drvdata *drvdata; + void __iomem *pf_base; + void __iomem *lut_base; + bool big_endian; + bool ep_presence; + bool pm_support; + struct regmap *scfg; + int index; }; +#define ls_pcie_lut_readl_addr(addr) ls_pcie_lut_readl(pcie, addr) +#define ls_pcie_pf_readl_addr(addr)ls_pcie_pf_readl(pcie, addr) #define to_ls_pcie(x) dev_get_drvdata((x)->dev) static bool ls_pcie_is_bridge(struct ls_pcie *pcie) @@ -86,6 +138,208 @@ static void ls_pcie_fix_error_response(struct ls_pcie *pcie) iowrite32(PCIE_ABSERR_SETTING, pci->dbi_base + PCIE_ABSERR); } +static u32 ls_pcie_lut_readl(struct ls_pcie *pcie, u32 off) +{ + if (pcie->big_endian) + return ioread32be(pcie->lut_base + off); + + return ioread32(pcie->lut_base + off); +} + +static void ls_pcie_lut_writel(struct ls_pcie *pcie, u32 off, u32 val) +{ + if (pcie->big_endian) + return iowrite32be(val, pcie->lut_base + off); + + return iowrite32(val, pcie->lut_base + off); + +} + +static u32 ls_pcie_pf_readl(struct ls_pcie *pcie, u32 off) +{ + if (pcie->big_endian) + return ioread32be(pcie->pf_base + off); + + return ioread32(pcie->pf_base + off); +} + +static void ls_pcie_pf_writel(struct ls_pcie *pcie, u32 off, u32 val) +{ + if (pcie->big_endian) + return iowrite32be(val, pcie->pf_base + off); + + return iowrite32(val, pcie->pf_base + off); + +} + +static void ls_pcie_send_turnoff_msg(struct ls_pcie *pcie) +{ + u32 val; + int ret; + + val = ls_pcie_pf_readl(pcie, LS_PCIE_PF_MCR); + val |= PF_MCR_PTOMR; + ls_pcie_pf_writel(pcie, LS_PCIE_PF_MCR, val); + + ret = readx_poll_timeout(ls_pcie_pf_readl_addr, LS_PCIE_PF_MCR, +val, !(val & PF_MCR_PTOMR), 100, 1); + if (ret) + dev_info(pcie->pci->dev, "poll turn off message timeout\n"); +} + +static void ls1021a_pcie_send_turnoff_msg(struct ls_pcie *pcie) +{ + u32 val; + + if (!pcie->scfg) { + dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n"); + return; + } + + /* Send Turn_off message */ + regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), &val); + val |= PMXMTTURNOFF; + regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val); + + mdelay(10); + + /* Clear Turn_off message */ + regmap_
[PATCH 1/7] PCI: dwc: Fix a bug of the case dw_pci->ops is NULL
From: Hou Zhiqiang The dw_pci->ops may be a NULL, and fix it by adding one more check. Signed-off-by: Hou Zhiqiang --- drivers/pci/controller/dwc/pcie-designware.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index b723e0cc41fb..bdf8938da9cd 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -140,7 +140,7 @@ u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size) int ret; u32 val; - if (pci->ops->read_dbi) + if (pci->ops && pci->ops->read_dbi) return pci->ops->read_dbi(pci, pci->dbi_base, reg, size); ret = dw_pcie_read(pci->dbi_base + reg, size, &val); @@ -155,7 +155,7 @@ void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val) { int ret; - if (pci->ops->write_dbi) { + if (pci->ops && pci->ops->write_dbi) { pci->ops->write_dbi(pci, pci->dbi_base, reg, size, val); return; } @@ -200,7 +200,7 @@ u32 dw_pcie_read_atu(struct dw_pcie *pci, u32 reg, size_t size) int ret; u32 val; - if (pci->ops->read_dbi) + if (pci->ops && pci->ops->read_dbi) return pci->ops->read_dbi(pci, pci->atu_base, reg, size); ret = dw_pcie_read(pci->atu_base + reg, size, &val); @@ -214,7 +214,7 @@ void dw_pcie_write_atu(struct dw_pcie *pci, u32 reg, size_t size, u32 val) { int ret; - if (pci->ops->write_dbi) { + if (pci->ops && pci->ops->write_dbi) { pci->ops->write_dbi(pci, pci->atu_base, reg, size, val); return; } @@ -283,7 +283,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, { u32 retries, val; - if (pci->ops->cpu_addr_fixup) + if (pci->ops && pci->ops->cpu_addr_fixup) cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr); if (pci->iatu_unroll_enabled) { @@ -470,7 +470,7 @@ int dw_pcie_link_up(struct dw_pcie *pci) { u32 val; - if (pci->ops->link_up) + if (pci->ops && pci->ops->link_up) return pci->ops->link_up(pci); val = readl(pci->dbi_base + PCIE_PORT_DEBUG1); -- 2.17.1
[PATCH 4/7] arm64: dts: layerscape: Add big-endian property for PCIe nodes
From: Hou Zhiqiang Add the big-endian property for LS1012A, LS1043A and LS1046A PCIe devicetree nodes. Signed-off-by: Hou Zhiqiang --- arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 1 + arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 3 +++ arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 +++ 3 files changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index ff19ec415b60..77a0d401c177 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -511,6 +511,7 @@ < 0 0 2 &gic 0 111 IRQ_TYPE_LEVEL_HIGH>, < 0 0 3 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>, < 0 0 4 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + big-endian; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 5c2e370f6316..70e07612da12 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -837,6 +837,7 @@ < 0 0 2 &gic 0 111 0x4>, < 0 0 3 &gic 0 112 0x4>, < 0 0 4 &gic 0 113 0x4>; + big-endian; status = "disabled"; }; @@ -863,6 +864,7 @@ < 0 0 2 &gic 0 121 0x4>, < 0 0 3 &gic 0 122 0x4>, < 0 0 4 &gic 0 123 0x4>; + big-endian; status = "disabled"; }; @@ -889,6 +891,7 @@ < 0 0 2 &gic 0 155 0x4>, < 0 0 3 &gic 0 156 0x4>, < 0 0 4 &gic 0 157 0x4>; + big-endian; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 0246d975a206..efcbfe8e5e1d 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -741,6 +741,7 @@ < 0 0 2 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, < 0 0 3 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, < 0 0 4 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + big-endian; status = "disabled"; }; @@ -777,6 +778,7 @@ < 0 0 2 &gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, < 0 0 3 &gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, < 0 0 4 &gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + big-endian; status = "disabled"; }; @@ -813,6 +815,7 @@ < 0 0 2 &gic GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>, < 0 0 3 &gic GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>, < 0 0 4 &gic GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; + big-endian; status = "disabled"; }; -- 2.17.1
[PATCH 3/7] dt-bindings: pci: layerscape-pci: Add a optional property big-endian
From: Hou Zhiqiang This property is to indicate the endianness when accessing the PEX_LUT and PF register block, so if these registers are implemented in big-endian, specify this property. Signed-off-by: Hou Zhiqiang --- Documentation/devicetree/bindings/pci/layerscape-pci.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index 99a386ea691c..2236d3f3089b 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -37,6 +37,10 @@ Required properties: of the data transferred from/to the IP block. This can avoid the software cache flush/invalid actions, and improve the performance significantly. +Optional properties: +- big-endian: If the PEX_LUT and PF register block is in big-endian, specify + this property. + Example: pcie@340 { -- 2.17.1
[PATCH 2/7] PCI: layerscape: Change to use the DWC common link-up check function
From: Hou Zhiqiang The current Layerscape PCIe driver directly uses the physical layer LTSSM code to check the link-up state, which treats the > L0 states as link-up. This is not correct, since there is not explicit map between link-up state and LTSSM. So this patch changes to use the DWC common link-up check function. Signed-off-by: Hou Zhiqiang --- drivers/pci/controller/dwc/pci-layerscape.c | 141 ++-- 1 file changed, 10 insertions(+), 131 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c index f24f79a70d9a..be404c16bcbe 100644 --- a/drivers/pci/controller/dwc/pci-layerscape.c +++ b/drivers/pci/controller/dwc/pci-layerscape.c @@ -22,12 +22,6 @@ #include "pcie-designware.h" -/* PEX1/2 Misc Ports Status Register */ -#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4) -#define LTSSM_STATE_SHIFT 20 -#define LTSSM_STATE_MASK 0x3f -#define LTSSM_PCIE_L0 0x11 /* L0 state */ - /* PEX Internal Configuration Registers */ #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ #define PCIE_ABSERR0x8d0 /* Bridge Slave Error Response Register */ @@ -36,19 +30,12 @@ #define PCIE_IATU_NUM 6 struct ls_pcie_drvdata { - u32 lut_offset; - u32 ltssm_shift; - u32 lut_dbg; const struct dw_pcie_host_ops *ops; - const struct dw_pcie_ops *dw_pcie_ops; }; struct ls_pcie { struct dw_pcie *pci; - void __iomem *lut; - struct regmap *scfg; const struct ls_pcie_drvdata *drvdata; - int index; }; #define to_ls_pcie(x) dev_get_drvdata((x)->dev) @@ -91,38 +78,6 @@ static void ls_pcie_disable_outbound_atus(struct ls_pcie *pcie) dw_pcie_disable_atu(pcie->pci, i, DW_PCIE_REGION_OUTBOUND); } -static int ls1021_pcie_link_up(struct dw_pcie *pci) -{ - u32 state; - struct ls_pcie *pcie = to_ls_pcie(pci); - - if (!pcie->scfg) - return 0; - - regmap_read(pcie->scfg, SCFG_PEXMSCPORTSR(pcie->index), &state); - state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK; - - if (state < LTSSM_PCIE_L0) - return 0; - - return 1; -} - -static int ls_pcie_link_up(struct dw_pcie *pci) -{ - struct ls_pcie *pcie = to_ls_pcie(pci); - u32 state; - - state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >> -pcie->drvdata->ltssm_shift) & -LTSSM_STATE_MASK; - - if (state < LTSSM_PCIE_L0) - return 0; - - return 1; -} - /* Forward error response of outbound non-posted requests */ static void ls_pcie_fix_error_response(struct ls_pcie *pcie) { @@ -155,33 +110,6 @@ static int ls_pcie_host_init(struct pcie_port *pp) return 0; } -static int ls1021_pcie_host_init(struct pcie_port *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct ls_pcie *pcie = to_ls_pcie(pci); - struct device *dev = pci->dev; - u32 index[2]; - int ret; - - pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, -"fsl,pcie-scfg"); - if (IS_ERR(pcie->scfg)) { - ret = PTR_ERR(pcie->scfg); - dev_err(dev, "No syscfg phandle specified\n"); - pcie->scfg = NULL; - return ret; - } - - if (of_property_read_u32_array(dev->of_node, - "fsl,pcie-scfg", index, 2)) { - pcie->scfg = NULL; - return -EINVAL; - } - pcie->index = index[1]; - - return ls_pcie_host_init(pp); -} - static int ls_pcie_msi_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -205,71 +133,25 @@ static int ls_pcie_msi_host_init(struct pcie_port *pp) return 0; } -static const struct dw_pcie_host_ops ls1021_pcie_host_ops = { - .host_init = ls1021_pcie_host_init, - .msi_host_init = ls_pcie_msi_host_init, -}; - static const struct dw_pcie_host_ops ls_pcie_host_ops = { .host_init = ls_pcie_host_init, .msi_host_init = ls_pcie_msi_host_init, }; -static const struct dw_pcie_ops dw_ls1021_pcie_ops = { - .link_up = ls1021_pcie_link_up, -}; - -static const struct dw_pcie_ops dw_ls_pcie_ops = { - .link_up = ls_pcie_link_up, -}; - -static const struct ls_pcie_drvdata ls1021_drvdata = { - .ops = &ls1021_pcie_host_ops, - .dw_pcie_ops = &dw_ls1021_pcie_ops, -}; - -static const struct ls_pcie_drvdata ls1043_drvdata = { - .lut_offset = 0x1, - .ltssm_shift = 24, - .lut_dbg = 0x7fc, - .ops = &ls_pcie_host_ops, - .dw_pcie_ops = &dw_ls_pcie_ops, -}; - -static const struct ls_pcie_drvdata ls1046_drvdata = { - .lut_offset = 0x8, - .ltssm_shift = 24, - .lut_dbg = 0x407fc, - .ops = &ls_pcie_host_ops, - .dw_pcie_ops = &dw_ls_
[PATCH 0/7] PCI: layerscape: Add power management support
From: Hou Zhiqiang This patch series is to add PCIe power management support for NXP Layerscape platfroms. Hou Zhiqiang (7): PCI: dwc: Fix a bug of the case dw_pci->ops is NULL PCI: layerscape: Change to use the DWC common link-up check function dt-bindings: pci: layerscape-pci: Add a optional property big-endian arm64: dts: layerscape: Add big-endian property for PCIe nodes dt-bindings: pci: layerscape-pci: Update the description of SCFG property dts: arm64: ls1043a: Add SCFG phandle for PCIe nodes PCI: layerscape: Add power management support .../bindings/pci/layerscape-pci.txt | 6 +- .../arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 1 + .../arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 + .../arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 + drivers/pci/controller/dwc/pci-layerscape.c | 473 ++ drivers/pci/controller/dwc/pcie-designware.c | 12 +- drivers/pci/controller/dwc/pcie-designware.h | 1 + 7 files changed, 388 insertions(+), 114 deletions(-) -- 2.17.1
Re: [PATCH] i2c: virtio: add a virtio i2c frontend driver
On 2020/9/4 下午9:21, Jie Deng wrote: On 2020/9/4 12:06, Jason Wang wrote: diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 293e7a0..70c8e30 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -21,6 +21,17 @@ config I2C_ALI1535 This driver can also be built as a module. If so, the module will be called i2c-ali1535. +config I2C_VIRTIO + tristate "Virtio I2C Adapter" + depends on VIRTIO I guess it should depend on some I2C module here. The dependency of I2C is included in the Kconfig in its parent directory. So there is nothing special to add here. Ok. +struct virtio_i2c_msg { + struct virtio_i2c_hdr hdr; + char *buf; + u8 status; Any reason for separating status out of virtio_i2c_hdr? The status is not from i2c_msg. You meant ic2_hdr? You embed status in virtio_i2c_msg anyway. So I put it out of virtio_i2c_hdr. Something like status or response is pretty common in virtio request (e.g net or scsi), if no special reason, it's better to keep it in the hdr. +}; + +/** + * struct virtio_i2c - virtio I2C data + * @vdev: virtio device for this controller + * @completion: completion of virtio I2C message + * @adap: I2C adapter for this controller + * @i2c_lock: lock for virtqueue processing + * @vq: the virtio virtqueue for communication + */ +struct virtio_i2c { + struct virtio_device *vdev; + struct completion completion; + struct i2c_adapter adap; + struct mutex i2c_lock; + struct virtqueue *vq; +}; + +static void virtio_i2c_msg_done(struct virtqueue *vq) +{ + struct virtio_i2c *vi = vq->vdev->priv; + + complete(&vi->completion); +} + +static int virtio_i2c_add_msg(struct virtqueue *vq, + struct virtio_i2c_msg *vmsg, + struct i2c_msg *msg) +{ + struct scatterlist *sgs[3], hdr, bout, bin, status; + int outcnt = 0, incnt = 0; + + if (!msg->len) + return -EINVAL; + + vmsg->hdr.addr = msg->addr; + vmsg->hdr.flags = msg->flags; + vmsg->hdr.len = msg->len; Missing endian conversion? You are right. Need conversion here. + + vmsg->buf = kzalloc(vmsg->hdr.len, GFP_KERNEL); + if (!vmsg->buf) + return -ENOMEM; + + sg_init_one(&hdr, &vmsg->hdr, sizeof(struct virtio_i2c_hdr)); + sgs[outcnt++] = &hdr; + if (vmsg->hdr.flags & I2C_M_RD) { + sg_init_one(&bin, vmsg->buf, msg->len); + sgs[outcnt + incnt++] = &bin; + } else { + memcpy(vmsg->buf, msg->buf, msg->len); + sg_init_one(&bout, vmsg->buf, msg->len); + sgs[outcnt++] = &bout; + } + sg_init_one(&status, &vmsg->status, sizeof(vmsg->status)); + sgs[outcnt + incnt++] = &status; + + return virtqueue_add_sgs(vq, sgs, outcnt, incnt, vmsg, GFP_KERNEL); +} + +static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct virtio_i2c *vi = i2c_get_adapdata(adap); + struct virtio_i2c_msg *vmsg_o, *vmsg_i; + struct virtqueue *vq = vi->vq; + unsigned long time_left; + int len, i, ret = 0; + + vmsg_o = kzalloc(sizeof(*vmsg_o), GFP_KERNEL); + if (!vmsg_o) + return -ENOMEM; It looks to me we can avoid the allocation by embedding virtio_i2c_msg into struct virtio_i2c; Yeah... That's better. Thanks. + + mutex_lock(&vi->i2c_lock); + vmsg_o->buf = NULL; + for (i = 0; i < num; i++) { + ret = virtio_i2c_add_msg(vq, vmsg_o, &msgs[i]); + if (ret) { + dev_err(&adap->dev, "failed to add msg[%d] to virtqueue.\n", i); + goto err_unlock_free; + } + + virtqueue_kick(vq); + + time_left = wait_for_completion_timeout(&vi->completion, adap->timeout); + if (!time_left) { + dev_err(&adap->dev, "msg[%d]: addr=0x%x timeout.\n", i, msgs[i].addr); + ret = i; + goto err_unlock_free; + } + + vmsg_i = (struct virtio_i2c_msg *)virtqueue_get_buf(vq, &len); + if (vmsg_i) { + /* vmsg_i should point to the same address with vmsg_o */ + if (vmsg_i != vmsg_o) { + dev_err(&adap->dev, "msg[%d]: addr=0x%x virtqueue error.\n", + i, vmsg_i->hdr.addr); + ret = i; + goto err_unlock_free; + } Does this imply in order completion of i2c device? (E.g what happens if multiple virtio i2c requests are submitted) Btw, this always use a single descriptor once a time which makes me suspect if a virtqueue(virtio) is really needed. It looks to me we can utilize the virtqueue by submit the request in a batch. I'm afraid not all physical devices support batch. Yes but I think I meant for the virtio device not the physical one. It's impossible to forbid batching if you have a queue anyway ... I'd like to keep the current design and consider your suggestion as a possible optimization in the future. Thanks. +} + +static void virtio_i2c_
Re: sa2ul.c:undefined reference to `crypto_authenc_extractkeys'
On Mon, Sep 07, 2020 at 11:12:53AM +0800, kernel test robot wrote: > tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > master > head: f4d51dffc6c01a9e94650d95ce0104964f8ae822 > commit: d2c8ac187fc922e73930a1b2f6a211e27f595d01 crypto: sa2ul - Add AEAD > algorithm support > date: 7 weeks ago > config: x86_64-randconfig-s022-20200907 (attached as .config) > compiler: gcc-9 (Debian 9.3.0-15) 9.3.0 > reproduce: > # apt-get install sparse > # sparse version: v0.6.2-191-g10164920-dirty > git checkout d2c8ac187fc922e73930a1b2f6a211e27f595d01 > # save the attached .config to linux build tree > make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 > > If you fix the issue, kindly add following tag as appropriate > Reported-by: kernel test robot > > All errors (new ones prefixed by >>): > >ld: drivers/crypto/sa2ul.o: in function `sa_aead_setkey.constprop.0': > >> sa2ul.c:(.text+0x3466): undefined reference to `crypto_authenc_extractkeys' Thanks for the report. This should fix it: ---8<--- The sa2ul driver uses crypto_authenc_extractkeys and therefore must select CRYPTO_AUTHENC. Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver") Reported-by: kernel test robot Signed-off-by: Herbert Xu diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index aa3a4ed07a66..c2950127def6 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -873,6 +873,7 @@ config CRYPTO_DEV_SA2UL select CRYPTO_AES select CRYPTO_AES_ARM64 select CRYPTO_ALGAPI + select CRYPTO_AUTHENC select HW_RANDOM select SG_SPLIT help -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] /dev/zero: also implement ->read
Le 06/09/2020 à 22:52, David Laight a écrit : From: Christophe Leroy Sent: 06 September 2020 19:36 Hi, Le 06/09/2020 à 20:21, Pavel Machek a écrit : Hi! Christophe reported a major speedup due to avoiding the iov_iter overhead, so just add this trivial function. Note that /dev/zero already implements both an iter and non-iter writes so this just makes it more symmetric. Christophe Leroy Signed-off-by: Christoph Hellwig Tested-by: Christophe Leroy Any idea what has happened to make the 'iter' version so bad? Exactly. Also it would be nice to note how the speedup was measured and what the speedup is. Was measured on an 8xx powerpc running at 132MHz with: dd if=/dev/zero of=/dev/null count=1M With the patch, dd displays a throughput of 113.5MB/s Without the patch it is 99.9MB/s That in itself isn't a problem. What was the throughput before any of these patches? I just remember another thread about the same test running a lot slower after one of the related changes. While this speeds up read /dev/zero (which is uncommon) if this is needed to get near the old performance then the changes to the 'iter' code will affect real workloads. If you are talking about the tests around the set_fs series from Christoph, I identified that the degradation was linked to CONFIG_STACKPROTECTOR_STRONG being selected by default, which provides unreliable results from one patch to another, GCC doing some strange things linked to unrelated changes. With CONFIG_STACKPROTECTOR set to N, I get stable performance and no degradation with any of the patches of the set_fs series. Christophe
[PATCH v3 2/2] dt-bindings: leds: Convert pwm to yaml
The example was adapted slightly to make use of the 'function' and 'color' properties. Suggested-by: Jacek Anaszewski Signed-off-by: Alexander Dahl Acked-by: Jacek Anaszewski --- Notes: v2 -> v3: * change license identifier to recommended one * added Acked-by .../devicetree/bindings/leds/leds-pwm.txt | 50 --- .../devicetree/bindings/leds/leds-pwm.yaml| 85 +++ 2 files changed, 85 insertions(+), 50 deletions(-) delete mode 100644 Documentation/devicetree/bindings/leds/leds-pwm.txt create mode 100644 Documentation/devicetree/bindings/leds/leds-pwm.yaml diff --git a/Documentation/devicetree/bindings/leds/leds-pwm.txt b/Documentation/devicetree/bindings/leds/leds-pwm.txt deleted file mode 100644 index 6c6583c35f2f.. --- a/Documentation/devicetree/bindings/leds/leds-pwm.txt +++ /dev/null @@ -1,50 +0,0 @@ -LED connected to PWM - -Required properties: -- compatible : should be "pwm-leds". - -Each LED is represented as a sub-node of the pwm-leds device. Each -node's name represents the name of the corresponding LED. - -LED sub-node properties: -- pwms : PWM property to point to the PWM device (phandle)/port (id) and to - specify the period time to be used: <&phandle id period_ns>; -- pwm-names : (optional) Name to be used by the PWM subsystem for the PWM device - For the pwms and pwm-names property please refer to: - Documentation/devicetree/bindings/pwm/pwm.txt -- max-brightness : Maximum brightness possible for the LED -- active-low : (optional) For PWMs where the LED is wired to supply - rather than ground. -- label : (optional) - see Documentation/devicetree/bindings/leds/common.txt -- linux,default-trigger : (optional) - see Documentation/devicetree/bindings/leds/common.txt - -Example: - -twl_pwm: pwm { - /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */ - compatible = "ti,twl6030-pwm"; - #pwm-cells = <2>; -}; - -twl_pwmled: pwmled { - /* provides one PWM (id 0 for Charing indicator LED) */ - compatible = "ti,twl6030-pwmled"; - #pwm-cells = <2>; -}; - -pwmleds { - compatible = "pwm-leds"; - kpad { - label = "omap4::keypad"; - pwms = <&twl_pwm 0 7812500>; - max-brightness = <127>; - }; - - charging { - label = "omap4:green:chrg"; - pwms = <&twl_pwmled 0 7812500>; - max-brightness = <255>; - }; -}; diff --git a/Documentation/devicetree/bindings/leds/leds-pwm.yaml b/Documentation/devicetree/bindings/leds/leds-pwm.yaml new file mode 100644 index ..c74867492424 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-pwm.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/leds-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LEDs connected to PWM + +maintainers: + - Pavel Machek + +description: + Each LED is represented as a sub-node of the pwm-leds device. Each + node's name represents the name of the corresponding LED. + +properties: + compatible: +const: pwm-leds + +patternProperties: + "^pwm-led-([0-9a-f])$": +type: object + +$ref: common.yaml# + +properties: + pwms: +description: + "PWM property to point to the PWM device (phandle)/port (id) + and to specify the period time to be used: + <&phandle id period_ns>;" + + pwm-names: +description: + "Name to be used by the PWM subsystem for the PWM device For + the pwms and pwm-names property please refer to: + Documentation/devicetree/bindings/pwm/pwm.txt" + + max-brightness: +description: + Maximum brightness possible for the LED + + active-low: +description: + For PWMs where the LED is wired to supply rather than ground. + +required: + - pwms + - max-brightness + +examples: + - | + +#include + +twl_pwm: pwm { +/* provides two PWMs (id 0, 1 for PWM1 and PWM2) */ +compatible = "ti,twl6030-pwm"; +#pwm-cells = <2>; +}; + +twl_pwmled: pwmled { +/* provides one PWM (id 0 for Charing indicator LED) */ +compatible = "ti,twl6030-pwmled"; +#pwm-cells = <2>; +}; + +pwm_leds { +compatible = "pwm-leds"; + +pwm-led-1 { +label = "omap4::keypad"; +pwms = <&twl_pwm 0 7812500>; +max-brightness = <127>; +}; + +pwm-led-2 { +color = ; +function = LED_FUNCTION_CHARGING; +pwms = <&twl_pwmled 0 7812500>; +max-brightness = <255>; +}; +}; + +... -- 2.20.1
[PATCH v3 0/2] leds: pwm: Make automatic labels work
Hei hei, for leds-gpio you can use the properties 'function' and 'color' in the devicetree node and omit 'label', the label is constructed automatically. This is a common feature supposed to be working for all LED drivers. However it did not yet work for the 'leds-pwm' driver. This series fixes the driver and takes the opportunity to update the dt-bindings accordingly. v3: - rebased on v5.9-rc4 - changed license of .yaml file to recommended one - added Acked-by v2: - rebased on v5.9-rc3 - added the dt-bindings update patch v1: - based on v5.9-rc2 - backport on v5.4.59 tested and working Greets Alex Alexander Dahl (2): leds: pwm: Allow automatic labels for DT based devices dt-bindings: leds: Convert pwm to yaml .../devicetree/bindings/leds/leds-pwm.txt | 50 --- .../devicetree/bindings/leds/leds-pwm.yaml| 85 +++ drivers/leds/leds-pwm.c | 9 +- 3 files changed, 93 insertions(+), 51 deletions(-) delete mode 100644 Documentation/devicetree/bindings/leds/leds-pwm.txt create mode 100644 Documentation/devicetree/bindings/leds/leds-pwm.yaml -- 2.20.1
[PATCH v3 1/2] leds: pwm: Allow automatic labels for DT based devices
If LEDs are configured through device tree and the property 'label' is omitted, the label is supposed to be generated from the properties 'function' and 'color' if present. While this works fine for e.g. the 'leds-gpio' driver, it did not for 'leds-pwm'. The reason is, you get this label naming magic only if you add a LED device through 'devm_led_classdev_register_ext()' and pass a pointer to the current device tree node. The approach to fix this was adopted from the 'leds-gpio' driver. For the following node from dts the LED appeared as 'led5' in sysfs before and as 'red:debug' after this change. pwm_leds { compatible = "pwm-leds"; led5 { function = LED_FUNCTION_DEBUG; color = ; pwms = <&pwm0 2 1000 0>; max-brightness = <127>; linux,default-trigger = "heartbeat"; panic-indicator; }; }; Signed-off-by: Alexander Dahl Acked-by: Jacek Anaszewski --- Notes: v2 -> v3: * added Acked-by drivers/leds/leds-pwm.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index ef7b91bd2064..a27a1d75a3e9 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -65,6 +65,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv, struct led_pwm *led, struct fwnode_handle *fwnode) { struct led_pwm_data *led_data = &priv->leds[priv->num_leds]; + struct led_init_data init_data = {}; int ret; led_data->active_low = led->active_low; @@ -90,7 +91,13 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv, pwm_init_state(led_data->pwm, &led_data->pwmstate); - ret = devm_led_classdev_register(dev, &led_data->cdev); + if (fwnode) { + init_data.fwnode = fwnode; + ret = devm_led_classdev_register_ext(dev, &led_data->cdev, +&init_data); + } else { + ret = devm_led_classdev_register(dev, &led_data->cdev); + } if (ret) { dev_err(dev, "failed to register PWM led for %s: %d\n", led->name, ret); -- 2.20.1
Re: [GIT PULL] xen: branch for v5.9-rc4
On 06.09.20 19:01, Linus Torvalds wrote: On Sat, Sep 5, 2020 at 9:44 PM Juergen Gross wrote: It contains a small series for fixing a problem with Xen PVH guests when running as backends (e.g. as dom0). Mapping other guests' memory now is working via ZONE_DEVICE, thus not requiring to abuse the memory hotplug functionality for that purpose. Tssk. This really isn't a bug-fix, it's clearly new development. I'm going to let it slide since it seems so contained, but don't do this. Thanks for taking it. I agree I should have spelled out the nature of the patch more clearly and add more reasoning why you might consider taking it. Juergen
[PATCH v5 3/7] perf util: Compare two streams
Stream is the branch history which is aggregated by the branch records from perf samples. Now we support the callchain as stream. If the callchain entries of one stream are fully matched with the callchain entries of another stream, we think two streams are matched. For example, cycles: 1, hits: 26.80% cycles: 1, hits: 27.30% --- --- main div.c:39 main div.c:39 main div.c:44 main div.c:44 Above two streams are matched (we don't consider the case that source code is changed). The matching logic is, compare the chain string first. If it's not matched, fallback to dso address comparison. Signed-off-by: Jin Yao --- v5: - Remove enum stream_type - Rebase to perf/core v4: - Remove original source line comparison code. tools/perf/util/callchain.c | 54 + tools/perf/util/callchain.h | 3 +++ 2 files changed, 57 insertions(+) diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9a9b56ed3f0a..7cab271e656b 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1599,3 +1599,57 @@ void callchain_cursor_reset(struct callchain_cursor *cursor) for (node = cursor->first; node != NULL; node = node->next) map__zput(node->map); } + +static bool chain_match(struct callchain_list *base_chain, + struct callchain_list *pair_chain) +{ + enum match_result match; + + match = match_chain_strings(base_chain->srcline, + pair_chain->srcline); + if (match != MATCH_ERROR) + return match == MATCH_EQ; + + match = match_chain_dso_addresses(base_chain->ms.map, + base_chain->ip, + pair_chain->ms.map, + pair_chain->ip); + + return match == MATCH_EQ; +} + +bool callchain_cnode_matched(struct callchain_node *base_cnode, +struct callchain_node *pair_cnode) +{ + struct callchain_list *base_chain, *pair_chain; + bool match = false; + + pair_chain = list_first_entry(&pair_cnode->val, + struct callchain_list, + list); + + list_for_each_entry(base_chain, &base_cnode->val, list) { + if (&pair_chain->list == &pair_cnode->val) + return false; + + if (!base_chain->srcline || !pair_chain->srcline) { + pair_chain = list_next_entry(pair_chain, list); + continue; + } + + match = chain_match(base_chain, pair_chain); + if (!match) + return false; + + pair_chain = list_next_entry(pair_chain, list); + } + + /* +* Say chain1 is ABC, chain2 is ABCD, we consider they are +* not fully matched. +*/ + if (pair_chain && (&pair_chain->list != &pair_cnode->val)) + return false; + + return match; +} diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 83398e5bbe4b..72134bed49d8 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -290,4 +290,7 @@ int callchain_branch_counts(struct callchain_root *root, u64 *branch_count, u64 *predicted_count, u64 *abort_count, u64 *cycles_count); +bool callchain_cnode_matched(struct callchain_node *base_cnode, +struct callchain_node *pair_cnode); + #endif /* __PERF_CALLCHAIN_H */ -- 2.17.1
[PATCH v5 7/7] perf diff: Support hot streams comparison
This patch enables perf-diff with "--stream" option. "--stream": Enable hot streams comparison Now let's see examples. perf record -b ... Generate perf.data.old with branch data perf record -b ... Generate perf.data with branch data perf diff --stream [ Matched hot streams ] hot chain pair 1: cycles: 1, hits: 27.77% cycles: 1, hits: 9.24% --- -- main div.c:39 main div.c:39 main div.c:44 main div.c:44 hot chain pair 2: cycles: 34, hits: 20.06%cycles: 27, hits: 16.98% --- -- __random_r random_r.c:360 __random_r random_r.c:360 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:380 __random_r random_r.c:380 __random_r random_r.c:357 __random_r random_r.c:357 __random random.c:293 __random random.c:293 __random random.c:293 __random random.c:293 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:288 __random random.c:288 rand rand.c:27 rand rand.c:27 rand rand.c:26 rand rand.c:26 rand@pltrand@plt rand@pltrand@plt compute_flag div.c:25 compute_flag div.c:25 compute_flag div.c:22 compute_flag div.c:22 main div.c:40 main div.c:40 main div.c:40 main div.c:40 main div.c:39 main div.c:39 hot chain pair 3: cycles: 9, hits: 4.48% cycles: 6, hits: 4.51% --- -- __random_r random_r.c:360 __random_r random_r.c:360 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:380 __random_r random_r.c:380 [ Hot streams in old perf data only ] hot chain 1: cycles: 18, hits: 6.75% -- __random_r random_r.c:360 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:380 __random_r random_r.c:357 __random random.c:293 __random random.c:293 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:288 rand rand.c:27 rand rand.c:26 rand@plt rand@plt compute_flag div.c:25 compute_flag div.c:22 main div.c:40 hot chain 2: cycles: 29, hits: 2.78% -- compute_flag div.c:22 main div.c:40 main div.c:40 main div.c:39 [ Hot streams in new perf data only ] hot chain 1: cycles: 4, hits: 4.54% -- main div.c:42 compute_flag div.c:28 hot chain 2: cycles: 5, hits: 3.51% -- main div.c:39 main div.c:44 main div.c:42 compute_flag div.c:28 Signed-off-by: Jin Yao --- v5: - Remove enum stream_type - Rebase to perf/core v4: - Remove the "--before" and "--after" options since they are for source line based comparison. In this patchset, we will not support source line based comparison. tools/perf/Documentation/perf-diff.txt | 4 + tools/perf/builtin-diff.c | 133 ++---
[PATCH v5 1/7] perf util: Create streams
We define the stream is the branch history which is aggregated by the branch records from perf samples. For example, the callchains aggregated from the branch records are considered as streams. By browsing the hot stream, we can understand the hot code path. Now we only support the callchain for stream. For measuring the hot level for a stream, we use the callchain_node->hit, higher is hotter. There may be many callchains sampled so we only focus on the top N hottest callchains. N is a user defined parameter or predefined default value (nr_streams_max). This patch creates an evsel_streams array per event, and saves the top N hottest streams in a stream array. So now we can get the per-event top N hottest streams. Signed-off-by: Jin Yao --- v5: - Remove enum stram_type - Rebase to perf/core v4: - Refactor the code - Rename patch name from 'perf util: Create streams for managing top N hottest callchains' to 'perf util: Create streams' v2: - Use zfree in free_evsel_streams(). tools/perf/util/Build| 1 + tools/perf/util/stream.c | 148 +++ tools/perf/util/stream.h | 23 ++ 3 files changed, 172 insertions(+) create mode 100644 tools/perf/util/stream.c create mode 100644 tools/perf/util/stream.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 8dcfca1a882f..3c8059186b09 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -95,6 +95,7 @@ perf-y += cloexec.o perf-y += call-path.o perf-y += rwsem.o perf-y += thread-stack.o +perf-y += stream.o perf-$(CONFIG_AUXTRACE) += auxtrace.o perf-$(CONFIG_AUXTRACE) += intel-pt-decoder/ perf-$(CONFIG_AUXTRACE) += intel-pt.o diff --git a/tools/perf/util/stream.c b/tools/perf/util/stream.c new file mode 100644 index ..015c1d07ce3a --- /dev/null +++ b/tools/perf/util/stream.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Compare and figure out the top N hottest streams + * Copyright (c) 2020, Intel Corporation. + * Author: Jin Yao + */ + +#include +#include +#include +#include "debug.h" +#include "hist.h" +#include "sort.h" +#include "stream.h" +#include "evlist.h" + +static void free_evsel_streams(struct evsel_streams *es, int nr_evsel) +{ + for (int i = 0; i < nr_evsel; i++) + zfree(&es[i].streams); + + free(es); +} + +static struct evsel_streams *create_evsel_streams(int nr_evsel, + int nr_streams_max) +{ + struct evsel_streams *es; + + es = calloc(nr_evsel, sizeof(struct evsel_streams)); + if (!es) + return NULL; + + for (int i = 0; i < nr_evsel; i++) { + struct evsel_streams *s = &es[i]; + + s->streams = calloc(nr_streams_max, sizeof(struct stream)); + if (!s->streams) + goto err; + + s->nr_streams_max = nr_streams_max; + s->evsel_idx = -1; + } + + return es; + +err: + free_evsel_streams(es, nr_evsel); + return NULL; +} + +/* + * The cnodes with high hit number are hot callchains. + */ +static void set_hot_cnode(struct evsel_streams *es, + struct callchain_node *cnode) +{ + int i, idx = 0; + u64 hit; + + if (es->nr_streams < es->nr_streams_max) { + i = es->nr_streams; + es->streams[i].cnode = cnode; + es->nr_streams++; + return; + } + + /* +* Considering a few number of hot streams, only use simple +* way to find the cnode with smallest hit number and replace. +*/ + hit = (es->streams[0].cnode)->hit; + for (i = 1; i < es->nr_streams; i++) { + if ((es->streams[i].cnode)->hit < hit) { + hit = (es->streams[i].cnode)->hit; + idx = i; + } + } + + if (cnode->hit > hit) + es->streams[idx].cnode = cnode; +} + +static void update_hot_callchain(struct hist_entry *he, +struct evsel_streams *es) +{ + struct rb_root *root = &he->sorted_chain; + struct rb_node *rb_node = rb_first(root); + struct callchain_node *cnode; + + while (rb_node) { + cnode = rb_entry(rb_node, struct callchain_node, rb_node); + set_hot_cnode(es, cnode); + rb_node = rb_next(rb_node); + } +} + +static void init_hot_callchain(struct hists *hists, struct evsel_streams *es) +{ + struct rb_node *next = rb_first_cached(&hists->entries); + + while (next) { + struct hist_entry *he; + + he = rb_entry(next, struct hist_entry, rb_node); + update_hot_callchain(he, es); + next = rb_next(&he->rb_node); + } +} + +static int evlist_init_callchain_streams(struct evlist *evlist, +struct evsel_streams *es, int n
[PATCH v5 6/7] perf util: Report hot streams
We show the streams separately. They are divided into different sections. 1. "Matched hot streams" 2. "Hot streams in old perf data only" 3. "Hot streams in new perf data only". For each stream, we report the cycles and hot percent (hits%). For example, cycles: 2, hits: 4.08% -- main div.c:42 compute_flag div.c:28 Signed-off-by: Jin Yao --- v5: - Rebase to perf/core v4: - Remove "Hot chains in old perf data but source line changed in new perf data" tools/perf/util/callchain.c | 13 tools/perf/util/callchain.h | 2 + tools/perf/util/stream.c| 123 tools/perf/util/stream.h| 3 + 4 files changed, 141 insertions(+) diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 90d31582393e..ce66a6308e87 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1685,3 +1685,16 @@ u64 callchain_total_hits(struct hists *hists) return chain_hits; } + +s64 callchain_avg_cycles(struct callchain_node *cnode) +{ + struct callchain_list *chain; + s64 cycles = 0; + + list_for_each_entry(chain, &cnode->val, list) { + if (chain->srcline && chain->branch_count) + cycles += chain->cycles_count / chain->branch_count; + } + + return cycles; +} diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 082f73524c9a..9c099f463723 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -296,4 +296,6 @@ bool callchain_cnode_matched(struct callchain_node *base_cnode, u64 callchain_total_hits(struct hists *hists); +s64 callchain_avg_cycles(struct callchain_node *cnode); + #endif /* __PERF_CALLCHAIN_H */ diff --git a/tools/perf/util/stream.c b/tools/perf/util/stream.c index 642316078e40..2d3dc7361ef1 100644 --- a/tools/perf/util/stream.c +++ b/tools/perf/util/stream.c @@ -199,3 +199,126 @@ void match_evsel_streams(struct evsel_streams *es_base, stream_link(base_stream, pair_stream); } } + +static void print_callchain_pair(struct stream *base_stream, int idx, +struct evsel_streams *es_base, +struct evsel_streams *es_pair) +{ + struct callchain_node *base_cnode = base_stream->cnode; + struct callchain_node *pair_cnode = base_stream->pair_cnode; + struct callchain_list *base_chain, *pair_chain; + char buf1[512], buf2[512], cbuf1[256], cbuf2[256]; + char *s1, *s2; + double pct; + + printf("\nhot chain pair %d:\n", idx); + + pct = (double)base_cnode->hit / (double)es_base->streams_hits; + scnprintf(buf1, sizeof(buf1), "cycles: %ld, hits: %.2f%%", + callchain_avg_cycles(base_cnode), pct * 100.0); + + pct = (double)pair_cnode->hit / (double)es_pair->streams_hits; + scnprintf(buf2, sizeof(buf2), "cycles: %ld, hits: %.2f%%", + callchain_avg_cycles(pair_cnode), pct * 100.0); + + printf("%35s\t%35s\n", buf1, buf2); + + printf("%35s\t%35s\n", + "---", + "--"); + + pair_chain = list_first_entry(&pair_cnode->val, + struct callchain_list, + list); + + list_for_each_entry(base_chain, &base_cnode->val, list) { + if (&pair_chain->list == &pair_cnode->val) + return; + + s1 = callchain_list__sym_name(base_chain, cbuf1, sizeof(cbuf1), + false); + s2 = callchain_list__sym_name(pair_chain, cbuf2, sizeof(cbuf2), + false); + + scnprintf(buf1, sizeof(buf1), "%35s\t%35s", s1, s2); + printf("%s\n", buf1); + pair_chain = list_next_entry(pair_chain, list); + } +} + +static void print_stream_callchain(struct stream *stream, int idx, + struct evsel_streams *es, bool pair) +{ + struct callchain_node *cnode = stream->cnode; + struct callchain_list *chain; + char buf[512], cbuf[256], *s; + double pct; + + printf("\nhot chain %d:\n", idx); + + pct = (double)cnode->hit / (double)es->streams_hits; + scnprintf(buf, sizeof(buf), "cycles: %ld, hits: %.2f%%", + callchain_avg_cycles(cnode), pct * 100.0); + + if (pair) { + printf("%35s\t%35s\n", "", buf); + printf("%35s\t%35s\n", + "", "--"); + } else { + printf("%35s\n", buf); + printf("%35s\n", "--"); + } + + list_for_each_entry(chain, &cnode->val, list) { + s = callchain_list__sym_name(chain, cbuf, sizeof(cbuf), false); + +
[PATCH v5 5/7] perf util: Calculate the sum of total streams hits
We have used callchain_node->hit to measure the hot level of one stream. This patch calculates the sum of hits of total streams. Thus in next patch, we can use following formula to report hot percent for one stream. hot percent = callchain_node->hit / sum of total hits Signed-off-by: Jin Yao --- v5: - Rebase to perf/core v4: - No functional change. v2: - Combine the variable decl line with its initial assignment in total_callchain_hits(). tools/perf/util/callchain.c | 32 tools/perf/util/callchain.h | 3 +++ tools/perf/util/stream.c| 2 ++ tools/perf/util/stream.h| 1 + 4 files changed, 38 insertions(+) diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 7cab271e656b..90d31582393e 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1653,3 +1653,35 @@ bool callchain_cnode_matched(struct callchain_node *base_cnode, return match; } + +static u64 count_callchain_hits(struct hist_entry *he) +{ + struct rb_root *root = &he->sorted_chain; + struct rb_node *rb_node = rb_first(root); + struct callchain_node *node; + u64 chain_hits = 0; + + while (rb_node) { + node = rb_entry(rb_node, struct callchain_node, rb_node); + chain_hits += node->hit; + rb_node = rb_next(rb_node); + } + + return chain_hits; +} + +u64 callchain_total_hits(struct hists *hists) +{ + struct rb_node *next = rb_first_cached(&hists->entries); + u64 chain_hits = 0; + + while (next) { + struct hist_entry *he = rb_entry(next, struct hist_entry, +rb_node); + + chain_hits += count_callchain_hits(he); + next = rb_next(&he->rb_node); + } + + return chain_hits; +} diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 72134bed49d8..082f73524c9a 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -13,6 +13,7 @@ struct ip_callchain; struct map; struct perf_sample; struct thread; +struct hists; #define HELP_PAD "\t\t\t\t" @@ -293,4 +294,6 @@ int callchain_branch_counts(struct callchain_root *root, bool callchain_cnode_matched(struct callchain_node *base_cnode, struct callchain_node *pair_cnode); +u64 callchain_total_hits(struct hists *hists); + #endif /* __PERF_CALLCHAIN_H */ diff --git a/tools/perf/util/stream.c b/tools/perf/util/stream.c index e96e21d6e07b..642316078e40 100644 --- a/tools/perf/util/stream.c +++ b/tools/perf/util/stream.c @@ -106,6 +106,8 @@ static void init_hot_callchain(struct hists *hists, struct evsel_streams *es) update_hot_callchain(he, es); next = rb_next(&he->rb_node); } + + es->streams_hits = callchain_total_hits(hists); } static int evlist_init_callchain_streams(struct evlist *evlist, diff --git a/tools/perf/util/stream.h b/tools/perf/util/stream.h index 2eb6f17a834e..56dfa90c810d 100644 --- a/tools/perf/util/stream.h +++ b/tools/perf/util/stream.h @@ -14,6 +14,7 @@ struct evsel_streams { int nr_streams_max; int nr_streams; int evsel_idx; + u64 streams_hits; }; struct evlist; -- 2.17.1
[PATCH v5 0/7] perf: Stream comparison
Sometimes, a small change in a hot function reducing the cycles of this function, but the overall workload doesn't get faster. It is interesting where the cycles are moved to. What it would like is to diff before/after streams. The stream is the branch history which is aggregated by the branch records from perf samples. For example, the callchains aggregated from the branch records. By browsing the hot stream, we can understand the hot code path. By browsing the hot streams, we can understand the hot code path. By comparing the cycles variation of same streams between old perf data and new perf data, we can understand if the cycles are moved to other codes. The before stream is the stream in perf.data.old. The after stream is the stream in perf.data. Diffing before/after streams compares top N hottest streams between two perf data files. If all entries of one stream in perf.data.old are fully matched with all entries of another stream in perf.data, we think two streams are matched, otherwise the streams are not matched. For example, cycles: 1, hits: 26.80% cycles: 1, hits: 27.30% -- -- main div.c:39 main div.c:39 main div.c:44 main div.c:44 The above streams are matched and we can see for the same streams the cycles (1) are equal and the callchain hit percents are slightly changed (26.80% vs. 27.30%). That's expected. Now let's see examples. perf record -b ... Generate perf.data.old with branch data perf record -b ... Generate perf.data with branch data perf diff --stream [ Matched hot streams ] hot chain pair 1: cycles: 1, hits: 27.77% cycles: 1, hits: 9.24% --- -- main div.c:39 main div.c:39 main div.c:44 main div.c:44 hot chain pair 2: cycles: 34, hits: 20.06%cycles: 27, hits: 16.98% --- -- __random_r random_r.c:360 __random_r random_r.c:360 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:380 __random_r random_r.c:380 __random_r random_r.c:357 __random_r random_r.c:357 __random random.c:293 __random random.c:293 __random random.c:293 __random random.c:293 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:288 __random random.c:288 rand rand.c:27 rand rand.c:27 rand rand.c:26 rand rand.c:26 rand@pltrand@plt rand@pltrand@plt compute_flag div.c:25 compute_flag div.c:25 compute_flag div.c:22 compute_flag div.c:22 main div.c:40 main div.c:40 main div.c:40 main div.c:40 main div.c:39 main div.c:39 hot chain pair 3: cycles: 9, hits: 4.48% cycles: 6, hits: 4.51% --- -- __random_r random_r.c:360 __random_r random_r.c:360 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:380 __random_r random_r.c:380 [ Hot streams in old perf data only ] hot chain 1: cycles: 18, hits: 6.75% -- __random_r random_r.c:360 __random_r random_r.c:388 __random_r random_r.c:388 __random_r random_r.c:380 __random_r random_r.c:357 __random random.c:293 __random random.c:293 __random random.c:291 __random random.c:291 __random random.c:291 __random random.c:288 rand rand.c:27 rand rand.c:26 rand@plt rand@plt compute_flag div.c:25 compute_flag div.c:22 main div.c:40 hot chain 2: cycles: 29,
[PATCH v5 4/7] perf util: Link stream pair
In previous patch, we have created an evsel_streams for one event, and top N hottest streams will be saved in a stream array in evsel_streams. This patch compares total streams among two evsel_streams. Once two streams are fully matched, they will be linked as a pair. From the pair, we can know which streams are matched. Signed-off-by: Jin Yao --- v5: - Remove enum stream_type v4: - New patch in v4. tools/perf/util/stream.c | 40 tools/perf/util/stream.h | 4 2 files changed, 44 insertions(+) diff --git a/tools/perf/util/stream.c b/tools/perf/util/stream.c index 7882a7f05d97..e96e21d6e07b 100644 --- a/tools/perf/util/stream.c +++ b/tools/perf/util/stream.c @@ -157,3 +157,43 @@ struct evsel_streams *evsel_streams_get(struct evsel_streams *es, return NULL; } + +static struct stream *stream_callchain_match(struct stream *base_stream, +struct evsel_streams *es_pair) +{ + for (int i = 0; i < es_pair->nr_streams; i++) { + struct stream *pair_stream = &es_pair->streams[i]; + + if (callchain_cnode_matched(base_stream->cnode, + pair_stream->cnode)) { + return pair_stream; + } + } + + return NULL; +} + +static struct stream *stream_match(struct stream *base_stream, + struct evsel_streams *es_pair) +{ + return stream_callchain_match(base_stream, es_pair); +} + +static void stream_link(struct stream *base_stream, struct stream *pair_stream) +{ + base_stream->pair_cnode = pair_stream->cnode; + pair_stream->pair_cnode = base_stream->cnode; +} + +void match_evsel_streams(struct evsel_streams *es_base, +struct evsel_streams *es_pair) +{ + for (int i = 0; i < es_base->nr_streams; i++) { + struct stream *base_stream = &es_base->streams[i]; + struct stream *pair_stream; + + pair_stream = stream_match(base_stream, es_pair); + if (pair_stream) + stream_link(base_stream, pair_stream); + } +} diff --git a/tools/perf/util/stream.h b/tools/perf/util/stream.h index 66f61d954eef..2eb6f17a834e 100644 --- a/tools/perf/util/stream.h +++ b/tools/perf/util/stream.h @@ -6,6 +6,7 @@ struct stream { struct callchain_node *cnode; + struct callchain_node *pair_cnode; }; struct evsel_streams { @@ -23,4 +24,7 @@ struct evsel_streams *perf_evlist__create_streams(struct evlist *evlist, struct evsel_streams *evsel_streams_get(struct evsel_streams *es, int nr_evsel, int evsel_idx); +void match_evsel_streams(struct evsel_streams *es_base, +struct evsel_streams *es_pair); + #endif /* __PERF_STREAM_H */ -- 2.17.1
[PATCH v5 2/7] perf util: Get the evsel_streams by evsel_idx
In previous patch, we have created evsel_streams array This patch returns the specified evsel_streams according to the evsel_idx. Signed-off-by: Jin Yao --- v5: - Rebase to perf/core v4: - Rename the patch from 'perf util: Return per-event callchain streams' to 'perf util: Get the evsel_streams by evsel_idx' tools/perf/util/stream.c | 11 +++ tools/perf/util/stream.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/tools/perf/util/stream.c b/tools/perf/util/stream.c index 015c1d07ce3a..7882a7f05d97 100644 --- a/tools/perf/util/stream.c +++ b/tools/perf/util/stream.c @@ -146,3 +146,14 @@ struct evsel_streams *perf_evlist__create_streams(struct evlist *evlist, return es; } + +struct evsel_streams *evsel_streams_get(struct evsel_streams *es, + int nr_evsel, int evsel_idx) +{ + for (int i = 0; i < nr_evsel; i++) { + if (es[i].evsel_idx == evsel_idx) + return &es[i]; + } + + return NULL; +} diff --git a/tools/perf/util/stream.h b/tools/perf/util/stream.h index c6844c5787cb..66f61d954eef 100644 --- a/tools/perf/util/stream.h +++ b/tools/perf/util/stream.h @@ -20,4 +20,7 @@ struct evlist; struct evsel_streams *perf_evlist__create_streams(struct evlist *evlist, int nr_streams_max); +struct evsel_streams *evsel_streams_get(struct evsel_streams *es, + int nr_evsel, int evsel_idx); + #endif /* __PERF_STREAM_H */ -- 2.17.1
[PATCH] ASoC: rt5682: Have global name clock option for parent clk
When adding parent clk(mclk) to wclk, this adds fallback option for the case where global clk name is used. Signed-off-by: Akshu Agrawal --- sound/soc/codecs/rt5682.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 93ebf0279b62..26928bc49bcb 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -2780,6 +2780,7 @@ static int rt5682_register_dai_clks(struct snd_soc_component *component) if (rt5682->mclk) { init.parent_data = &(struct clk_parent_data){ .fw_name = "mclk", + .name = __clk_get_name(rt5682->mclk), }; init.num_parents = 1; } -- 2.20.1
[PATCHv3] selftests: rtnetlink: load fou module for kci_test_encap_fou() test
The kci_test_encap_fou() test from kci_test_encap() in rtnetlink.sh needs the fou module to work. Otherwise it will fail with: $ ip netns exec "$testns" ip fou add port ipproto 47 RTNETLINK answers: No such file or directory Error talking to the kernel Add the CONFIG_NET_FOU into the config file as well. Which needs at least to be set as a loadable module. Signed-off-by: Po-Hsu Lin --- tools/testing/selftests/net/config | 1 + tools/testing/selftests/net/rtnetlink.sh | 6 ++ 2 files changed, 7 insertions(+) diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config index 3b42c06b..c5e50ab 100644 --- a/tools/testing/selftests/net/config +++ b/tools/testing/selftests/net/config @@ -31,3 +31,4 @@ CONFIG_NET_SCH_ETF=m CONFIG_NET_SCH_NETEM=y CONFIG_TEST_BLACKHOLE_DEV=m CONFIG_KALLSYMS=y +CONFIG_NET_FOU=m diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 7c38a90..a711b3e 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -520,6 +520,11 @@ kci_test_encap_fou() return $ksft_skip fi + if ! /sbin/modprobe -q -n fou; then + echo "SKIP: module fou is not found" + return $ksft_skip + fi + /sbin/modprobe -q fou ip -netns "$testns" fou add port ipproto 47 2>/dev/null if [ $? -ne 0 ];then echo "FAIL: can't add fou port , skipping test" @@ -540,6 +545,7 @@ kci_test_encap_fou() return 1 fi + /sbin/modprobe -q -r fou echo "PASS: fou" } -- 2.7.4
Re: [PATCH v9 0/2] phy: Add USB PHY support on Intel LGM SoC
Hi Kishon, Vinod, Kindly, can you please merge it if there's no further comments. Rob given Reviewed-by tag to USB-PHY dt_schema YAML patch. Philipp Zabel given Reviewed-by tag to USB-PHY driver patch. Please consider and do the needful. Regards Vadivel On 28/8/2020 10:23 am, Ramuthevar,Vadivel MuruganX wrote: The USB PHY provides the optimized for low power dissipation while active, idle, or on standby. Requires minimal external components, a single resistor, for best operation. Supports 10/5-Gbps high-speed data transmission rates through 3-m USB 3.x cable --- v9: - Vinod review comments update - remove depends on USB_SUPPORT - replace ret variable by 0 in return statement - replace dev_info by dev_dbg - handle ret and extcon_get_state separately v8-resend: - Correct the typo error in my previous patch v8: - Rebase to V5.9-rc1 v7: - No Change v6: - No Change v5: - As per Felipe and Greg's suggestion usb phy driver reviewed patches changed the folder from drivers/usb/phy to drivers/phy - Reviewed-By tag added in commit message v4: - Andy's review comments addressed - drop the excess error debug prints - error check optimized - merge the split line to one line v3: - Andy's review comments update - hardcode return value changed to actual return value from the callee - add error check is fixed according to the above - correct the assignment in redundant - combine the split line into one line v2: - Address Phillip's review comments - replace devm_reset_control_get() by devm_reset_control_get_exclusive() - re-design the assert and deassert fucntion calls as per review comments - address kbuild bot warnings - add the comments v1: - initial version --- dt-bindings: usb: Add USB PHY support for Intel LGM SoC v9: - No Change v8-resend: - No change v8: - No Change v7: - Fixed the bot issue: usb-phy@e7e0: '#phy-cells' is a required property v6: - Fixed the bot issue. - replace node-name by usb-phy@ in example v5: - Reviewed-By tag added v4: - No Change v3: - No Change v2: - No Change v1: - initial version Ramuthevar Vadivel Murugan (2): dt-bindings: phy: Add USB PHY support for Intel LGM SoC phy: Add USB3 PHY support for Intel LGM SoC .../devicetree/bindings/phy/intel,lgm-usb-phy.yaml | 58 + drivers/phy/Kconfig| 10 + drivers/phy/Makefile | 1 + drivers/phy/phy-lgm-usb.c | 281 + 4 files changed, 350 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/intel,lgm-usb-phy.yaml create mode 100644 drivers/phy/phy-lgm-usb.c
[PATCH 5/9] perf metric: Release expr_parse_ctx after testing
The test_generic_metric() missed to release entries in the pctx. Asan reported following leak (and more): Direct leak of 128 byte(s) in 1 object(s) allocated from: #0 0x7f4c9396980e in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10780e) #1 0x55f7e748cc14 in hashmap_grow (/home/namhyung/project/linux/tools/perf/perf+0x90cc14) #2 0x55f7e748d497 in hashmap__insert (/home/namhyung/project/linux/tools/perf/perf+0x90d497) #3 0x55f7e7341667 in hashmap__set /home/namhyung/project/linux/tools/perf/util/hashmap.h:111 #4 0x55f7e7341667 in expr__add_ref util/expr.c:120 #5 0x55f7e7292436 in prepare_metric util/stat-shadow.c:783 #6 0x55f7e729556d in test_generic_metric util/stat-shadow.c:858 #7 0x55f7e712390b in compute_single tests/parse-metric.c:128 #8 0x55f7e712390b in __compute_metric tests/parse-metric.c:180 #9 0x55f7e712446d in compute_metric tests/parse-metric.c:196 #10 0x55f7e712446d in test_dcache_l2 tests/parse-metric.c:295 #11 0x55f7e712446d in test__parse_metric tests/parse-metric.c:355 #12 0x55f7e70be09b in run_test tests/builtin-test.c:410 #13 0x55f7e70be09b in test_and_print tests/builtin-test.c:440 #14 0x55f7e70c101a in __cmd_test tests/builtin-test.c:661 #15 0x55f7e70c101a in cmd_test tests/builtin-test.c:807 #16 0x55f7e7126214 in run_builtin /home/namhyung/project/linux/tools/perf/perf.c:312 #17 0x55f7e6fc41a8 in handle_internal_command /home/namhyung/project/linux/tools/perf/perf.c:364 #18 0x55f7e6fc41a8 in run_argv /home/namhyung/project/linux/tools/perf/perf.c:408 #19 0x55f7e6fc41a8 in main /home/namhyung/project/linux/tools/perf/perf.c:538 #20 0x7f4c93492cc9 in __libc_start_main ../csu/libc-start.c:308 Fixes: 6d432c4c8aa56 ("perf tools: Add test_generic_metric function") Signed-off-by: Namhyung Kim --- tools/perf/util/stat-shadow.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index e1ba6c1b916a..a5f42c22c484 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -853,14 +853,16 @@ static void generic_metric(struct perf_stat_config *config, double test_generic_metric(struct metric_expr *mexp, int cpu, struct runtime_stat *st) { struct expr_parse_ctx pctx; - double ratio; + double ratio = 0.0; if (prepare_metric(mexp->metric_events, mexp->metric_refs, &pctx, cpu, st) < 0) - return 0.; + goto out; if (expr__parse(&ratio, &pctx, mexp->metric_expr, 1)) - return 0.; + ratio = 0.0; +out: + expr__ctx_clear(&pctx); return ratio; } -- 2.28.0.526.ge36021eeef-goog
[PATCH 6/9] perf metric: Free metric when it failed to resolve
The metricgroup__add_metric() can find multiple match for a metric group and it's possible to fail. Also it can fail in the middle like in resolve_metric() even for single metric. In those cases, the intermediate list and ids will be leaked like: Direct leak of 3 byte(s) in 1 object(s) allocated from: #0 0x7f4c938f40b5 in strdup (/lib/x86_64-linux-gnu/libasan.so.5+0x920b5) #1 0x55f7e71c1bef in __add_metric util/metricgroup.c:683 #2 0x55f7e71c31d0 in add_metric util/metricgroup.c:906 #3 0x55f7e71c3844 in metricgroup__add_metric util/metricgroup.c:940 #4 0x55f7e71c488d in metricgroup__add_metric_list util/metricgroup.c:993 #5 0x55f7e71c488d in parse_groups util/metricgroup.c:1045 #6 0x55f7e71c60a4 in metricgroup__parse_groups_test util/metricgroup.c:1087 #7 0x55f7e71235ae in __compute_metric tests/parse-metric.c:164 #8 0x55f7e7124650 in compute_metric tests/parse-metric.c:196 #9 0x55f7e7124650 in test_recursion_fail tests/parse-metric.c:318 #10 0x55f7e7124650 in test__parse_metric tests/parse-metric.c:356 #11 0x55f7e70be09b in run_test tests/builtin-test.c:410 #12 0x55f7e70be09b in test_and_print tests/builtin-test.c:440 #13 0x55f7e70c101a in __cmd_test tests/builtin-test.c:661 #14 0x55f7e70c101a in cmd_test tests/builtin-test.c:807 #15 0x55f7e7126214 in run_builtin /home/namhyung/project/linux/tools/perf/perf.c:312 #16 0x55f7e6fc41a8 in handle_internal_command /home/namhyung/project/linux/tools/perf/perf.c:364 #17 0x55f7e6fc41a8 in run_argv /home/namhyung/project/linux/tools/perf/perf.c:408 #18 0x55f7e6fc41a8 in main /home/namhyung/project/linux/tools/perf/perf.c:538 #19 0x7f4c93492cc9 in __libc_start_main ../csu/libc-start.c:308 Fixes: 83de0b7d535de ("perf metric: Collect referenced metrics in struct metric_ref_node") Signed-off-by: Namhyung Kim --- tools/perf/util/metricgroup.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index b28c09447c10..c8904e471a71 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -939,7 +939,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, ret = add_metric(&list, pe, metric_no_group, &m, NULL, &ids); if (ret) - return ret; + goto out; /* * Process any possible referenced metrics @@ -948,12 +948,14 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, ret = resolve_metric(metric_no_group, &list, map, &ids); if (ret) - return ret; + goto out; } /* End of pmu events. */ - if (!has_match) - return -EINVAL; + if (!has_match) { + ret = -EINVAL; + goto out; + } list_for_each_entry(m, &list, nd) { if (events->len > 0) @@ -968,9 +970,14 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, } } +out: + /* +* add to metric_list so that they can be released +* even if it's failed +*/ list_splice(&list, metric_list); expr_ids__exit(&ids); - return 0; + return ret; } static int metricgroup__add_metric_list(const char *list, bool metric_no_group, -- 2.28.0.526.ge36021eeef-goog
[PATCH 9/9] perf test: Free formats for perf pmu parse test
The following leaks were detected by ASAN: Indirect leak of 360 byte(s) in 9 object(s) allocated from: #0 0x7fecc305180e in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10780e) #1 0x560578f6dce5 in perf_pmu__new_format util/pmu.c:1333 #2 0x560578f752fc in perf_pmu_parse util/pmu.y:59 #3 0x560578f6a8b7 in perf_pmu__format_parse util/pmu.c:73 #4 0x560578e07045 in test__pmu tests/pmu.c:155 #5 0x560578de109b in run_test tests/builtin-test.c:410 #6 0x560578de109b in test_and_print tests/builtin-test.c:440 #7 0x560578de401a in __cmd_test tests/builtin-test.c:661 #8 0x560578de401a in cmd_test tests/builtin-test.c:807 #9 0x560578e49354 in run_builtin /home/namhyung/project/linux/tools/perf/perf.c:312 #10 0x560578ce71a8 in handle_internal_command /home/namhyung/project/linux/tools/perf/perf.c:364 #11 0x560578ce71a8 in run_argv /home/namhyung/project/linux/tools/perf/perf.c:408 #12 0x560578ce71a8 in main /home/namhyung/project/linux/tools/perf/perf.c:538 #13 0x7fecc2b7acc9 in __libc_start_main ../csu/libc-start.c:308 Fixes: cff7f956ec4a1 ("perf tests: Move pmu tests into separate object") Signed-off-by: Namhyung Kim --- tools/perf/tests/pmu.c | 1 + tools/perf/util/pmu.c | 11 +++ tools/perf/util/pmu.h | 1 + 3 files changed, 13 insertions(+) diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 5c11fe2b3040..714e6830a758 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -173,6 +173,7 @@ int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) ret = 0; } while (0); + perf_pmu__del_formats(&formats); test_format_dir_put(format); return ret; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 555cb3524c25..d41caeb35cf6 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1354,6 +1354,17 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to) set_bit(b, bits); } +void perf_pmu__del_formats(struct list_head *formats) +{ + struct perf_pmu_format *fmt, *tmp; + + list_for_each_entry_safe(fmt, tmp, formats, list) { + list_del(&fmt->list); + free(fmt->name); + free(fmt); + } +} + static int sub_non_neg(int a, int b) { if (b > a) diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index b63c4c5e335e..a64e9c9ce731 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -94,6 +94,7 @@ int perf_pmu__new_format(struct list_head *list, char *name, int config, unsigned long *bits); void perf_pmu__set_format(unsigned long *bits, long from, long to); int perf_pmu__format_parse(char *dir, struct list_head *head); +void perf_pmu__del_formats(struct list_head *formats); struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); -- 2.28.0.526.ge36021eeef-goog
[PATCH 1/9] perf evlist: Fix cpu/thread map leak
Asan reported leak of cpu and thread maps as they have one more refcount than released. I found that after setting evlist maps it should release it's refcount. It seems to be broken from the beginning so I chose the original commit as the culprit. But not sure how it's applied to stable trees since there are many changes in the code after that. Fixes: 7e2ed097538c5 ("perf evlist: Store pointer to the cpu and thread maps") Fixes: 4112eb1899c0e ("perf evlist: Default to syswide target when no thread/cpu maps set") Signed-off-by: Namhyung Kim --- tools/perf/util/evlist.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e3fa3bf7498a..c0768c61eb43 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -946,6 +946,10 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) perf_evlist__set_maps(&evlist->core, cpus, threads); + /* as evlist now has references, put count here */ + perf_cpu_map__put(cpus); + perf_thread_map__put(threads); + return 0; out_delete_threads: @@ -1273,11 +1277,12 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist) goto out_put; perf_evlist__set_maps(&evlist->core, cpus, threads); -out: - return err; + + perf_thread_map__put(threads); out_put: perf_cpu_map__put(cpus); - goto out; +out: + return err; } int evlist__open(struct evlist *evlist) -- 2.28.0.526.ge36021eeef-goog
[PATCH 3/9] perf parse-event: Fix memory leak in evsel->unit
The evsel->unit borrows a pointer of pmu event or alias instead of owns a string. But tool event (duration_time) passes a result of strdup() caused a leak. It was found by ASAN during metric test: Direct leak of 210 byte(s) in 70 object(s) allocated from: #0 0x7fe366fca0b5 in strdup (/lib/x86_64-linux-gnu/libasan.so.5+0x920b5) #1 0x559fbbcc6ea3 in add_event_tool util/parse-events.c:414 #2 0x559fbbcc6ea3 in parse_events_add_tool util/parse-events.c:1414 #3 0x559fbbd8474d in parse_events_parse util/parse-events.y:439 #4 0x559fbbcc95da in parse_events__scanner util/parse-events.c:2096 #5 0x559fbbcc95da in __parse_events util/parse-events.c:2141 #6 0x559fbbc28555 in check_parse_id tests/pmu-events.c:406 #7 0x559fbbc28555 in check_parse_id tests/pmu-events.c:393 #8 0x559fbbc28555 in check_parse_cpu tests/pmu-events.c:415 #9 0x559fbbc28555 in test_parsing tests/pmu-events.c:498 #10 0x559fbbc0109b in run_test tests/builtin-test.c:410 #11 0x559fbbc0109b in test_and_print tests/builtin-test.c:440 #12 0x559fbbc03e69 in __cmd_test tests/builtin-test.c:695 #13 0x559fbbc03e69 in cmd_test tests/builtin-test.c:807 #14 0x559fbbc691f4 in run_builtin /home/namhyung/project/linux/tools/perf/perf.c:312 #15 0x559fbbb071a8 in handle_internal_command /home/namhyung/project/linux/tools/perf/perf.c:364 #16 0x559fbbb071a8 in run_argv /home/namhyung/project/linux/tools/perf/perf.c:408 #17 0x559fbbb071a8 in main /home/namhyung/project/linux/tools/perf/perf.c:538 #18 0x7fe366b68cc9 in __libc_start_main ../csu/libc-start.c:308 Fixes: f0fbb114e3025 ("perf stat: Implement duration_time as a proper event") Signed-off-by: Namhyung Kim --- tools/perf/util/parse-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b35e4bb1cecb..ece321ccf599 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -416,7 +416,7 @@ static int add_event_tool(struct list_head *list, int *idx, return -ENOMEM; evsel->tool_event = tool_event; if (tool_event == PERF_TOOL_DURATION_TIME) - evsel->unit = strdup("ns"); + evsel->unit = "ns"; return 0; } -- 2.28.0.526.ge36021eeef-goog
Re: [PATCH v3 1/3] dt-bindings: iommu: Add binding for MediaTek MT8167 IOMMU
On Sun, 2020-09-06 at 17:19 +0200, Fabien Parent wrote: > This commit adds IOMMU binding documentation and larb port definitions > for the MT8167 SoC. > > Signed-off-by: Fabien Parent > Acked-by: Rob Herring > --- > > V3: Added mt8167-larb-port.h file for iommu port definitions > V2: no change > > --- > .../bindings/iommu/mediatek,iommu.txt | 1 + > include/dt-bindings/memory/mt8167-larb-port.h | 49 +++ > 2 files changed, 50 insertions(+) > create mode 100644 include/dt-bindings/memory/mt8167-larb-port.h > > diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > index c1ccd8582eb2..f7a348f48e0d 100644 > --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > @@ -61,6 +61,7 @@ Required properties: > "mediatek,mt6779-m4u" for mt6779 which uses generation two m4u HW. > "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses >generation one m4u HW. > + "mediatek,mt8167-m4u" for mt8167 which uses generation two m4u HW. > "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW. > "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW. > - reg : m4u register base and size. Please also add this line in the iommu-cells property: dt-bindings/memory/mt8167-larb-port.h for mt8167. > diff --git a/include/dt-bindings/memory/mt8167-larb-port.h > b/include/dt-bindings/memory/mt8167-larb-port.h > new file mode 100644 > index ..4dd44d1037a7 > --- /dev/null > +++ b/include/dt-bindings/memory/mt8167-larb-port.h > @@ -0,0 +1,49 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (c) 2020 BayLibre, SAS > + * Author: Fabien Parent If I'm not wrong, the first version was created by: Honghui Zhang the original author should be kept. > + */ > +#ifndef __DTS_IOMMU_PORT_MT8167_H > +#define __DTS_IOMMU_PORT_MT8167_H > + > +#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port)) > + > +#define M4U_LARB0_ID 0 > +#define M4U_LARB1_ID 1 > +#define M4U_LARB2_ID 2 > + > +/* larb0 */ > +#define M4U_PORT_DISP_OVL0 MTK_M4U_ID(M4U_LARB0_ID, 0) > +#define M4U_PORT_DISP_RDMA0 MTK_M4U_ID(M4U_LARB0_ID, 1) > +#define M4U_PORT_DISP_WDMA0 MTK_M4U_ID(M4U_LARB0_ID, 2) > +#define M4U_PORT_DISP_RDMA1 MTK_M4U_ID(M4U_LARB0_ID, 3) > +#define M4U_PORT_MDP_RDMAMTK_M4U_ID(M4U_LARB0_ID, 4) > +#define M4U_PORT_MDP_WDMAMTK_M4U_ID(M4U_LARB0_ID, 5) > +#define M4U_PORT_MDP_WROTMTK_M4U_ID(M4U_LARB0_ID, 6) > +#define M4U_PORT_DISP_FAKE MTK_M4U_ID(M4U_LARB0_ID, 7) > + > +/* IMG larb1*/ > +#define M4U_PORT_CAM_IMGOMTK_M4U_ID(M4U_LARB1_ID, 0) > +#define M4U_PORT_CAM_IMG2O MTK_M4U_ID(M4U_LARB1_ID, 1) > +#define M4U_PORT_CAM_LSCIMTK_M4U_ID(M4U_LARB1_ID, 2) > +#define M4U_PORT_CAM_ESFKO MTK_M4U_ID(M4U_LARB1_ID, 3) > +#define M4U_PORT_CAM_AAO MTK_M4U_ID(M4U_LARB1_ID, 4) > +#define M4U_PORT_VENC_RECMTK_M4U_ID(M4U_LARB1_ID, 5) > +#define M4U_PORT_VENC_BSDMA MTK_M4U_ID(M4U_LARB1_ID, 6) > +#define M4U_PORT_VENC_RD_COMVMTK_M4U_ID(M4U_LARB1_ID, 7) > +#define M4U_PORT_CAM_IMGIMTK_M4U_ID(M4U_LARB1_ID, 8) > +#define M4U_PORT_VENC_CUR_LUMA MTK_M4U_ID(M4U_LARB1_ID, 9) > +#define M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB1_ID, 10) > +#define M4U_PORT_VENC_REF_LUMA MTK_M4U_ID(M4U_LARB1_ID, 11) > +#define M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB1_ID, 12) > + > +/* VDEC larb2*/ > +#define M4U_PORT_HW_VDEC_MC_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) > +#define M4U_PORT_HW_VDEC_PP_EXT MTK_M4U_ID(M4U_LARB2_ID, 1) > +#define M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB2_ID, 2) > +#define M4U_PORT_HW_VDEC_AVC_MV_EXT MTK_M4U_ID(M4U_LARB2_ID, 3) > +#define M4U_PORT_HW_VDEC_PRED_RD_EXT MTK_M4U_ID(M4U_LARB2_ID, 4) > +#define M4U_PORT_HW_VDEC_PRED_WR_EXT MTK_M4U_ID(M4U_LARB2_ID, 5) > +#define M4U_PORT_HW_VDEC_PPWRAP_EXT MTK_M4U_ID(M4U_LARB2_ID, 6) > + > +#endif
[PATCH 7/9] perf metric: Do not free metric when failed to resolve
It's dangerous to free the original metric when it's called from resolve_metric() as it's already in the metric_list and might have other resources too. Instead, it'd better let them bail out and be released properly at the later stage. So add a check when it's called from metricgroup__add_metric() and release it. Also make sure that mp is set properly. Fixes: 83de0b7d535de ("perf metric: Collect referenced metrics in struct metric_ref_node") Signed-off-by: Namhyung Kim --- tools/perf/util/metricgroup.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index c8904e471a71..ab5030fcfed4 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -672,7 +672,6 @@ static int __add_metric(struct list_head *metric_list, m->has_constraint = metric_no_group || metricgroup__has_constraint(pe); INIT_LIST_HEAD(&m->metric_refs); m->metric_refs_cnt = 0; - *mp = m; parent = expr_ids__alloc(ids); if (!parent) { @@ -685,6 +684,7 @@ static int __add_metric(struct list_head *metric_list, free(m); return -ENOMEM; } + *mp = m; } else { /* * We got here for the referenced metric, via the @@ -719,8 +719,11 @@ static int __add_metric(struct list_head *metric_list, * all the metric's IDs and add it to the parent context. */ if (expr__find_other(pe->metric_expr, NULL, &m->pctx, runtime) < 0) { - expr__ctx_clear(&m->pctx); - free(m); + if (m->metric_refs_cnt == 0) { + expr__ctx_clear(&m->pctx); + free(m); + *mp = NULL; + } return -EINVAL; } -- 2.28.0.526.ge36021eeef-goog
[PATCH 4/9] perf test: Fix memory leaks in parse-metric test
It didn't release resources when there's an error so the test_recursion_fail() will leak some memory. Fixes: 0a507af9c681a ("perf tests: Add parse metric test for ipc metric") Signed-off-by: Namhyung Kim --- tools/perf/tests/parse-metric.c | 14 +- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c index 23db8acc492d..cd7331aac3bd 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -153,8 +153,10 @@ static int __compute_metric(const char *name, struct value *vals, return -ENOMEM; cpus = perf_cpu_map__new("0"); - if (!cpus) + if (!cpus) { + evlist__delete(evlist); return -ENOMEM; + } perf_evlist__set_maps(&evlist->core, cpus, NULL); @@ -163,10 +165,11 @@ static int __compute_metric(const char *name, struct value *vals, false, false, &metric_events); if (err) - return err; + goto out; - if (perf_evlist__alloc_stats(evlist, false)) - return -1; + err = perf_evlist__alloc_stats(evlist, false); + if (err) + goto out; /* Load the runtime stats with given numbers for events. */ runtime_stat__init(&st); @@ -178,13 +181,14 @@ static int __compute_metric(const char *name, struct value *vals, if (name2 && ratio2) *ratio2 = compute_single(&metric_events, evlist, &st, name2); +out: /* ... clenup. */ metricgroup__rblist_exit(&metric_events); runtime_stat__exit(&st); perf_evlist__free_stats(evlist); perf_cpu_map__put(cpus); evlist__delete(evlist); - return 0; + return err; } static int compute_metric(const char *name, struct value *vals, double *ratio) -- 2.28.0.526.ge36021eeef-goog
[PATCHSET 0/9] perf tools: Fix various memory leaks
Hello, I've found and fixed a bunch of memory leaks during perf pmu and metric tests with address sanitizer. Before this, the tests were mostly failed due to the leaks since ASAN makes it return non-zero. Now I'm seeing no error with ASAN like below: $ ./perf test pmu metric 9: Parse perf pmu format : Ok 10: PMU events: 10.1: PMU event table sanity : Ok 10.2: PMU event map aliases : Ok 10.3: Parsing of PMU event table metrics : Skip (some metrics failed) 10.4: Parsing of PMU event table metrics with fake PMUs : Ok 67: Parse and process metrics : Ok The failure in 10.3 seems due to parse errors like below: Multiple errors dropping message: unknown term 'filter_opc' for pmu 'uncore_cbox_0' (valid terms: event,edge,inv,umask,cmask,config,config1,config2,name,period,freq, branch_type,time,call-graph,stack-size,no-inherit,inherit,max-stack, nr,no-overwrite,overwrite,driver-config,percore,aux-output,aux-sample-size) Parse event failed metric 'DRAM_Parallel_Reads' id 'arb/event=0x80,umask=0x2,thresh=1/' expr 'arb@event\=0x80\,umask\=0x2@ / arb@event\=0x80\,umask\=0x2\,thresh\=1@' Error string 'unknown term 'thresh' for pmu 'uncore_arb'' help 'valid terms: event,edge,inv,umask,cmask,config,config1,config2,name,period,freq, branch_type,time,call-graph,stack-size,no-inherit,inherit,max-stack, nr,no-overwrite,overwrite,driver-config,percore,aux-output,aux-sample-size' The patches are also available at 'perf/metric-fix-v1' branch on git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git Thanks Namhyung Namhyung Kim (9): perf evlist: Fix cpu/thread map leak perf parse-event: Fix cpu map leaks perf parse-event: Fix memory leak in evsel->unit perf test: Fix memory leaks in parse-metric test perf metric: Release expr_parse_ctx after testing perf metric: Free metric when it failed to resolve perf metric: Do not free metric when failed to resolve perf test: Free aliases for PMU event map aliases test perf test: Free formats for perf pmu parse test tools/perf/tests/parse-metric.c | 14 +- tools/perf/tests/pmu-events.c | 5 + tools/perf/tests/pmu.c | 1 + tools/perf/util/evlist.c| 11 --- tools/perf/util/metricgroup.c | 26 ++ tools/perf/util/parse-events.c | 9 +++-- tools/perf/util/pmu.c | 13 - tools/perf/util/pmu.h | 2 ++ tools/perf/util/stat-shadow.c | 8 +--- 9 files changed, 67 insertions(+), 22 deletions(-) -- 2.28.0.526.ge36021eeef-goog
[PATCH 8/9] perf test: Free aliases for PMU event map aliases test
The aliases were never released causing the following leaks: Indirect leak of 1224 byte(s) in 9 object(s) allocated from: #0 0x7feefb830628 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x107628) #1 0x56332c8f1b62 in __perf_pmu__new_alias util/pmu.c:322 #2 0x56332c8f401f in pmu_add_cpu_aliases_map util/pmu.c:778 #3 0x56332c792ce9 in __test__pmu_event_aliases tests/pmu-events.c:295 #4 0x56332c792ce9 in test_aliases tests/pmu-events.c:367 #5 0x56332c76a09b in run_test tests/builtin-test.c:410 #6 0x56332c76a09b in test_and_print tests/builtin-test.c:440 #7 0x56332c76ce69 in __cmd_test tests/builtin-test.c:695 #8 0x56332c76ce69 in cmd_test tests/builtin-test.c:807 #9 0x56332c7d2214 in run_builtin /home/namhyung/project/linux/tools/perf/perf.c:312 #10 0x56332c6701a8 in handle_internal_command /home/namhyung/project/linux/tools/perf/perf.c:364 #11 0x56332c6701a8 in run_argv /home/namhyung/project/linux/tools/perf/perf.c:408 #12 0x56332c6701a8 in main /home/namhyung/project/linux/tools/perf/perf.c:538 #13 0x7feefb359cc9 in __libc_start_main ../csu/libc-start.c:308 Cc: John Garry Fixes: 956a78356c24c ("perf test: Test pmu-events aliases") Signed-off-by: Namhyung Kim --- tools/perf/tests/pmu-events.c | 5 + tools/perf/util/pmu.c | 2 +- tools/perf/util/pmu.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index eb19f9a0bc15..d3517a74d95e 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -274,6 +274,7 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) int res = 0; bool use_uncore_table; struct pmu_events_map *map = __test_pmu_get_events_map(); + struct perf_pmu_alias *a, *tmp; if (!map) return -1; @@ -347,6 +348,10 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) pmu_name, alias->name); } + list_for_each_entry_safe(a, tmp, &aliases, list) { + list_del(&a->list); + perf_pmu_free_alias(a); + } free(pmu); return res; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f1688e1f6ed7..555cb3524c25 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -274,7 +274,7 @@ static void perf_pmu_update_alias(struct perf_pmu_alias *old, } /* Delete an alias entry. */ -static void perf_pmu_free_alias(struct perf_pmu_alias *newalias) +void perf_pmu_free_alias(struct perf_pmu_alias *newalias) { zfree(&newalias->name); zfree(&newalias->desc); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 44ccbdbb1c37..b63c4c5e335e 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -113,6 +113,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu); bool pmu_uncore_alias_match(const char *pmu_name, const char *name); +void perf_pmu_free_alias(struct perf_pmu_alias *alias); int perf_pmu__convert_scale(const char *scale, char **end, double *sval); -- 2.28.0.526.ge36021eeef-goog
[PATCH 2/9] perf parse-event: Fix cpu map leaks
Like evlist cpu map, evsel's cpu map should have proper refcount by releasing the original count after creation. This fixes the following ASAN report: Direct leak of 840 byte(s) in 70 object(s) allocated from: #0 0x7fe36703f628 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x107628) #1 0x559fbbf611ca in cpu_map__trim_new /home/namhyung/project/linux/tools/lib/perf/cpumap.c:79 #2 0x559fbbf6229c in perf_cpu_map__new /home/namhyung/project/linux/tools/lib/perf/cpumap.c:237 #3 0x559fbbcc6c6d in __add_event util/parse-events.c:357 #4 0x559fbbcc6c6d in add_event_tool util/parse-events.c:408 #5 0x559fbbcc6c6d in parse_events_add_tool util/parse-events.c:1414 #6 0x559fbbd8474d in parse_events_parse util/parse-events.y:439 #7 0x559fbbcc95da in parse_events__scanner util/parse-events.c:2096 #8 0x559fbbcc95da in __parse_events util/parse-events.c:2141 #9 0x559fbbc2788b in check_parse_id tests/pmu-events.c:406 #10 0x559fbbc2788b in check_parse_id tests/pmu-events.c:393 #11 0x559fbbc2788b in check_parse_fake tests/pmu-events.c:436 #12 0x559fbbc2788b in metric_parse_fake tests/pmu-events.c:553 #13 0x559fbbc27e2d in test_parsing_fake tests/pmu-events.c:599 #14 0x559fbbc27e2d in test_parsing_fake tests/pmu-events.c:574 #15 0x559fbbc0109b in run_test tests/builtin-test.c:410 #16 0x559fbbc0109b in test_and_print tests/builtin-test.c:440 #17 0x559fbbc03e69 in __cmd_test tests/builtin-test.c:695 #18 0x559fbbc03e69 in cmd_test tests/builtin-test.c:807 #19 0x559fbbc691f4 in run_builtin /home/namhyung/project/linux/tools/perf/perf.c:312 #20 0x559fbbb071a8 in handle_internal_command /home/namhyung/project/linux/tools/perf/perf.c:364 #21 0x559fbbb071a8 in run_argv /home/namhyung/project/linux/tools/perf/perf.c:408 #22 0x559fbbb071a8 in main /home/namhyung/project/linux/tools/perf/perf.c:538 #23 0x7fe366b68cc9 in __libc_start_main ../csu/libc-start.c:308 And I've failed which commit introduced this bug as the code was heavily changed since then. ;-/ Signed-off-by: Namhyung Kim --- tools/perf/util/parse-events.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index c4d2394e2b2d..b35e4bb1cecb 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -360,8 +360,11 @@ __add_event(struct list_head *list, int *idx, event_attr_init(attr); evsel = evsel__new_idx(attr, *idx); - if (!evsel) + if (!evsel) { + if (!pmu) + perf_cpu_map__put(cpus); return NULL; + } (*idx)++; evsel->core.cpus = perf_cpu_map__get(cpus); @@ -369,6 +372,8 @@ __add_event(struct list_head *list, int *idx, evsel->core.system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; + if (!pmu) + perf_cpu_map__put(cpus); if (name) evsel->name = strdup(name); -- 2.28.0.526.ge36021eeef-goog
Re: [PATCH v3 3/3] iommu/mediatek: add support for MT8167
On Sun, 2020-09-06 at 17:19 +0200, Fabien Parent wrote: > Add support for the IOMMU on MT8167 > > Signed-off-by: Fabien Parent > --- > > V3: > * use LEGACY_IVRP_PADDR flag instead of using a platform data member > V2: > * removed if based on m4u_plat, and using instead the new > has_legacy_ivrp_paddr member that was introduced in patch 2. > > --- > drivers/iommu/mtk_iommu.c | 8 > drivers/iommu/mtk_iommu.h | 1 + > 2 files changed, 9 insertions(+) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index b1f85a7e9346..6079f6a23c74 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -817,6 +817,13 @@ static const struct mtk_iommu_plat_data mt6779_data = { > .larbid_remap = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}}, > }; > > +static const struct mtk_iommu_plat_data mt8167_data = { > + .m4u_plat = M4U_MT8167, > + .flags= HAS_4GB_MODE | RESET_AXI | HAS_LEGACY_IVRP_PADDR, The 4GB mode flow was improved at[1] which has just been applied. If you add 4gb_mode flag but don't have "mt8167-infracfg", the probe may be failed. [1] https://lore.kernel.org/linux-iommu/20200904112117.gc16...@8bytes.org/T/#m613e9926735d07ad004fddbbcedaa50b5afacca1 > + .inv_sel_reg = REG_MMU_INV_SEL_GEN1, > + .larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */ > +}; > + > static const struct mtk_iommu_plat_data mt8173_data = { > .m4u_plat = M4U_MT8173, > .flags= HAS_4GB_MODE | HAS_BCLK | RESET_AXI | > @@ -835,6 +842,7 @@ static const struct mtk_iommu_plat_data mt8183_data = { > static const struct of_device_id mtk_iommu_of_ids[] = { > { .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data}, > { .compatible = "mediatek,mt6779-m4u", .data = &mt6779_data}, > + { .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data}, > { .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data}, > { .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data}, > {} > diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h > index 122925dbe547..df32b3e3408b 100644 > --- a/drivers/iommu/mtk_iommu.h > +++ b/drivers/iommu/mtk_iommu.h > @@ -39,6 +39,7 @@ enum mtk_iommu_plat { > M4U_MT2701, > M4U_MT2712, > M4U_MT6779, > + M4U_MT8167, > M4U_MT8173, > M4U_MT8183, > };
[PATCH] PM: : fix @em_pd kernel-doc warning
From: Randy Dunlap Fix kernel-doc warning in : ../include/linux/device.h:613: warning: Function parameter or member 'em_pd' not described in 'device' Fixes: 1bc138c62295 ("PM / EM: add support for other devices than CPUs in Energy Model") Signed-off-by: Randy Dunlap Cc: Lukasz Luba Cc: Rafael J. Wysocki --- include/linux/device.h |1 + 1 file changed, 1 insertion(+) --- lnx-59-rc4.orig/include/linux/device.h +++ lnx-59-rc4/include/linux/device.h @@ -454,6 +454,7 @@ struct dev_links_info { * @pm_domain: Provide callbacks that are executed during system suspend, * hibernation, system resume and during runtime PM transitions * along with subsystem-level and driver-level callbacks. + * @em_pd: device's energy model performance domain * @pins: For device pin management. * See Documentation/driver-api/pinctl.rst for details. * @msi_list: Hosts MSI descriptors