Re: [PATCH] staging: sm750fb: Convert camel case to snake case
On Tue, Apr 06, 2021 at 11:36:41AM +0200, Greg KH wrote: > On Tue, Apr 06, 2021 at 02:18:41AM -0700, Pavle Rohalj wrote: > > - struct dvi_ctrl_device *pCurrentDviCtrl; > > + struct dvi_ctrl_device *p_current_dvi_ctrl; > > Does this change make sense? Why keep the "p_" here? We do not need or > use, this type of variable naming in the kernel. > > Also, please break this up into a patch series where you do one > structure change at a time. > > thanks, > > greg k-h Thank you for the input. Makes sense why we would not want to include type information in variable names. I will send a patchset with changes broken up into smaller chunks soon. -Pavle
Re: [PATCH v2] media: venus : hfi: add venus image info into smem
Hi Bjorn, Thanks for your review comments. I have addressed all in the latest patch v3. couldn't think of a shorter name for variables without losing the readability so kept as it is. Thanks, Dikshita On 2021-03-30 09:29, Bjorn Andersson wrote: On Fri 26 Mar 01:33 CDT 2021, Dikshita Agarwal wrote: Fill fw version info into smem to be printed as part of soc info. Signed-off-by: Dikshita Agarwal Changes since v1: adressed comments from stephen. removed unwanted code. --- drivers/media/platform/qcom/venus/hfi_msgs.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 06a1908..6b6d33c9 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "core.h" @@ -14,6 +15,10 @@ #include "hfi_msgs.h" #include "hfi_parser.h" +#define SMEM_IMG_VER_TBL 469 +#define VER_STR_SZ 128 +#define SMEM_IMG_INDEX_VENUS 14 * 128 14 is the index, 128 is the element size, so this is now an "offset". + static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, struct hfi_msg_event_notify_pkt *pkt) { @@ -239,15 +244,27 @@ static void sys_get_prop_image_version(struct device *dev, struct hfi_msg_sys_property_info_pkt *pkt) { + size_t smem_blk_sz = 0; You shouldn't need to initialize smem_blk_sz if you check the return value of qcom_smem_get() first. + u8 *smem_tbl_ptr; + u8 *img_ver; int req_bytes; req_bytes = pkt->hdr.size - sizeof(*pkt); - if (req_bytes < 128 || !pkt->data[1] || pkt->num_properties > 1) + if (req_bytes < VER_STR_SZ || !pkt->data[1] || pkt->num_properties > 1) /* bad packet */ return; - dev_dbg(dev, VDBGL "F/W version: %s\n", (u8 *)>data[1]); + img_ver = (u8 *)>data[1]; + + dev_dbg(dev, VDBGL "F/W version: %s\n", img_ver); + + smem_tbl_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, + SMEM_IMG_VER_TBL, _blk_sz); 80 chars is just a guideline and this looks prettier if you avoid the line wrap. That said, if you pick shorter names for smem_tbl_ptr and smem_blk_sz you probably even have to worry. + if ((SMEM_IMG_INDEX_VENUS + VER_STR_SZ) <= smem_blk_sz && + smem_tbl_ptr) In English you're trying to determine: "did qcom_smem_get() return a valid pointer and is the item's size at least as big as we need". So just write that in C: if (smem_tbl_ptr && smem_blk_sz >= SMEM_IMG_INDEX_VENUS + VER_STR_SZ) + memcpy(smem_tbl_ptr + SMEM_IMG_INDEX_VENUS, + img_ver, VER_STR_SZ); Again, please avoid the line wrap... Regards, Bjorn } static void hfi_sys_property_info(struct venus_core *core, -- 2.7.4
[PATCH v3] media: venus : hfi: add venus image info into smem
Fill fw version info into smem to be printed as part of soc info. Signed-off-by: Dikshita Agarwal changes since v2: - adressed all review comments. --- drivers/media/platform/qcom/venus/hfi_msgs.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 06a1908..74cfc4f 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "core.h" @@ -14,6 +15,10 @@ #include "hfi_msgs.h" #include "hfi_parser.h" +#define SMEM_IMG_VER_TBL 469 +#define VER_STR_SZ 128 +#define SMEM_IMG_OFFSET_VENUS (14 * 128) + static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, struct hfi_msg_event_notify_pkt *pkt) { @@ -239,15 +244,27 @@ static void sys_get_prop_image_version(struct device *dev, struct hfi_msg_sys_property_info_pkt *pkt) { + u8 *smem_tbl_ptr; + u8 *img_ver; int req_bytes; + size_t smem_blk_sz; req_bytes = pkt->hdr.size - sizeof(*pkt); - if (req_bytes < 128 || !pkt->data[1] || pkt->num_properties > 1) + if (req_bytes < VER_STR_SZ || !pkt->data[1] || pkt->num_properties > 1) /* bad packet */ return; - dev_dbg(dev, VDBGL "F/W version: %s\n", (u8 *)>data[1]); + img_ver = (u8 *)>data[1]; + + dev_dbg(dev, VDBGL "F/W version: %s\n", img_ver); + + smem_tbl_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, + SMEM_IMG_VER_TBL, _blk_sz); + if (smem_tbl_ptr && + smem_blk_sz >= SMEM_IMG_OFFSET_VENUS + VER_STR_SZ) + memcpy(smem_tbl_ptr + SMEM_IMG_OFFSET_VENUS, + img_ver, VER_STR_SZ); } static void hfi_sys_property_info(struct venus_core *core, -- 2.7.4
Re: [PATCH v7 5/8] pwm: core: Support new PWM_STAGGERING_ALLOWED flag
On Tue, Apr 06, 2021 at 06:41:37PM +0200, Clemens Gruber wrote: > If the flag PWM_STAGGERING_ALLOWED is set on a channel, the PWM driver > may (if supported by the HW) delay the ON time of the channel relative > to the channel number. > This does not alter the duty cycle ratio and is only relevant for PWM > chips with less prescalers than channels, which would otherwise assert > multiple or even all enabled channels at the same time. > > If this feature is supported by the driver and the flag is set on > multiple channels, their ON times are spread out to improve EMI and > reduce current spikes. As said in reply to patch 4/8 already: I don't like this idea and think this should be made explicit using a new offset member in struct pwm_state instead. That's because I think that the wave form a PWM generates should be (completely) defined by the consumer and not by a mix between consumer and device tree. Also the consumer has no (sane) way to determine if staggering is in use or not. One side effect (at least for the pca9685) is that when programming a new duty cycle it takes a bit longer than without staggering until the new setting is active. Another objection I have is that we already have some technical debt because there are already two different types of drivers (.apply vs .config+.set_polarity+.enable+.disable) and I would like to unify this first before introducing new stuff. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | https://www.pengutronix.de/ | signature.asc Description: PGP signature
[PATCH] media: sun8i-di: Fix rumtime PM imbalance in deinterlace_start_streaming
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error. Signed-off-by: Dinghao Liu --- drivers/media/platform/sunxi/sun8i-di/sun8i-di.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c index ed863bf5ea80..671e4a928993 100644 --- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c @@ -589,7 +589,7 @@ static int deinterlace_start_streaming(struct vb2_queue *vq, unsigned int count) int ret; if (V4L2_TYPE_IS_OUTPUT(vq->type)) { - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "Failed to enable module\n"); -- 2.17.1
[PATCH] media: platform: sti: Fix rumtime PM imbalance in regs_show
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error. Signed-off-by: Dinghao Liu --- drivers/media/platform/sti/bdisp/bdisp-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c index 2b270093009c..a27f638df11c 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-debug.c +++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c @@ -480,7 +480,7 @@ static int regs_show(struct seq_file *s, void *data) int ret; unsigned int i; - ret = pm_runtime_get_sync(bdisp->dev); + ret = pm_runtime_resume_and_get(bdisp->dev); if (ret < 0) { seq_puts(s, "Cannot wake up IP\n"); return 0; -- 2.17.1
Re: [RESEND PATCH v5 2/2] bio: add limit_bio_size sysfs
On Wed, Apr 07, 2021 at 10:21:17AM +0900, Changheun Lee wrote: > > On 3/16/21 12:44 AM, Changheun Lee wrote: > > > Add limit_bio_size block sysfs node to limit bio size. > > > Queue flag QUEUE_FLAG_LIMIT_BIO_SIZE will be set if limit_bio_size is set. > > > And bio max size will be limited by queue max sectors via > > > QUEUE_FLAG_LIMIT_BIO_SIZE set. > > > > > > Signed-off-by: Changheun Lee > > > --- > > > Documentation/ABI/testing/sysfs-block | 10 ++ > > > Documentation/block/queue-sysfs.rst | 7 +++ > > > block/blk-sysfs.c | 3 +++ > > > 3 files changed, 20 insertions(+) > > > > > > diff --git a/Documentation/ABI/testing/sysfs-block > > > b/Documentation/ABI/testing/sysfs-block > > > index e34cdeeeb9d4..86a7b15410cf 100644 > > > --- a/Documentation/ABI/testing/sysfs-block > > > +++ b/Documentation/ABI/testing/sysfs-block > > > @@ -316,3 +316,13 @@ Description: > > > does not complete in this time then the block driver timeout > > > handler is invoked. That timeout handler can decide to retry > > > the request, to fail it or to start a device recovery strategy. > > > + > > > +What:/sys/block//queue/limit_bio_size > > > +Date:Feb, 2021 > > > +Contact: Changheun Lee > > > +Description: > > > + (RW) Toggle for set/clear QUEUE_FLAG_LIMIT_BIO_SIZE queue flag. > > > + Queue flag QUEUE_FLAG_LIMIT_BIO_SIZE will be set if > > > limit_bio_size > > > + is set. And bio max size will be limited by queue max sectors. > > > + QUEUE_FLAG_LIMIT_BIO_SIZE will be cleared if limit_bio_size is > > > + cleard. And limit of bio max size will be cleard. > > > diff --git a/Documentation/block/queue-sysfs.rst > > > b/Documentation/block/queue-sysfs.rst > > > index 2638d3446b79..cd371a821855 100644 > > > --- a/Documentation/block/queue-sysfs.rst > > > +++ b/Documentation/block/queue-sysfs.rst > > > @@ -273,4 +273,11 @@ devices are described in the ZBC (Zoned Block > > > Commands) and ZAC > > > do not support zone commands, they will be treated as regular block > > > devices > > > and zoned will report "none". > > > > > > +limit_bio_size (RW) > > > +--- > > > +This indicates QUEUE_FLAG_LIMIT_BIO_SIZE queue flag value. And > > > +QUEUE_FLAG_LIMIT_BIO_SIZE can be changed via set(1)/clear(0) this node. > > > +bio max size will be limited by queue max sectors via set this node. And > > > +limit of bio max size will be cleard via clear this node. > > > + > > > Jens Axboe , February 2009 > > > diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c > > > index b513f1683af0..840d97f427e6 100644 > > > --- a/block/blk-sysfs.c > > > +++ b/block/blk-sysfs.c > > > @@ -288,6 +288,7 @@ QUEUE_SYSFS_BIT_FNS(nonrot, NONROT, 1); > > > QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0); > > > QUEUE_SYSFS_BIT_FNS(iostats, IO_STAT, 0); > > > QUEUE_SYSFS_BIT_FNS(stable_writes, STABLE_WRITES, 0); > > > +QUEUE_SYSFS_BIT_FNS(limit_bio_size, LIMIT_BIO_SIZE, 0); > > > #undef QUEUE_SYSFS_BIT_FNS > > > > > > static ssize_t queue_zoned_show(struct request_queue *q, char *page) > > > @@ -615,6 +616,7 @@ QUEUE_RW_ENTRY(queue_nonrot, "rotational"); > > > QUEUE_RW_ENTRY(queue_iostats, "iostats"); > > > QUEUE_RW_ENTRY(queue_random, "add_random"); > > > QUEUE_RW_ENTRY(queue_stable_writes, "stable_writes"); > > > +QUEUE_RW_ENTRY(queue_limit_bio_size, "limit_bio_size"); > > > > > > static struct attribute *queue_attrs[] = { > > > _requests_entry.attr, > > > @@ -648,6 +650,7 @@ static struct attribute *queue_attrs[] = { > > > _rq_affinity_entry.attr, > > > _iostats_entry.attr, > > > _stable_writes_entry.attr, > > > + _limit_bio_size_entry.attr, > > > _random_entry.attr, > > > _poll_entry.attr, > > > _wc_entry.attr, > > > > Has it been considered to introduce a function to set the BIO size limit > > instead of introducing a new sysfs attribute? See also > > blk_queue_max_hw_sectors(). > > A function to set has been not considered yet. > But sysfs attribute should be supported I think. Because it can be > different depending on each system environment including policy. But what tool is now responsible for setting this new value? Where will it get that information from? And why can't the kernel just automatically set this correctly in the first place without any need for userspace interaction? thanks, greg k-h
Re: [PATCH] staging: rtl8712: avoid multiple line dereference
On Wed, Apr 07, 2021 at 01:15:17AM +0200, Sergei Krainov wrote: > fix post-commit hook checkpatch issues: > > WARNING: Avoid multiple line dereference - prefer > 'adapter->mlmepriv.cur_network.network.InfrastructureMode' > + adapter->mlmepriv.cur_network.network. > + InfrastructureMode) > > WARNING: Avoid multiple line dereference - prefer > 'adapter->registrypriv.dev_network.MacAddress' > + adapter->registrypriv. > + dev_network.MacAddress; > > WARNING: Avoid multiple line dereference - prefer > 'pnetwork->network.Configuration.FHConfig.DwellTime' > + le32_to_cpu(pnetwork->network.Configuration.FHConfig. > + DwellTime); > > WARNING: Avoid multiple line dereference - prefer > 'pnetwork->network.Configuration.FHConfig.HopPattern' > + le32_to_cpu(pnetwork->network.Configuration. > + FHConfig.HopPattern); > > WARNING: Avoid multiple line dereference - prefer 'pmlmepriv->scanned_queue' > + r8712_find_network(> > + scanned_queue, > > WARNING: Avoid multiple line dereference - prefer 'pmlmepriv->scanned_queue' > + r8712_find_network(> > + scanned_queue, > > WARNING: Avoid multiple line dereference - prefer 'pstapriv->sta_hash_lock' > + spin_lock_irqsave(> > + sta_hash_lock, irqL2); > > WARNING: Avoid multiple line dereference - prefer 'pstapriv->sta_hash_lock' > + spin_unlock_irqrestore(&(pstapriv-> > + sta_hash_lock), irqL2); > > WARNING: Avoid multiple line dereference - prefer 'pmlmepriv->scanned_queue' > + r8712_find_network(> > + scanned_queue, > > WARNING: Avoid multiple line dereference - prefer > 'pnetwork->network.MacAddress' > + pnetwork->network. > + MacAddress); > > WARNING: Avoid multiple line dereference - prefer 'pmlmepriv->scanned_queue' > + ptarget_wlan = r8712_find_network(> > + scanned_queue, > > WARNING: Avoid multiple line dereference - prefer > 'adapter->securitypriv.AuthAlgrthm' > + if (adapter->securitypriv. > + AuthAlgrthm == 2) { > > WARNING: Avoid multiple line dereference - prefer > 'adapter->securitypriv.binstallGrpkey' > + adapter->securitypriv. > + binstallGrpkey = > > WARNING: Avoid multiple line dereference - prefer > 'adapter->securitypriv.busetkipkey' > + adapter->securitypriv. > + busetkipkey = > > WARNING: Avoid multiple line dereference - prefer > 'adapter->securitypriv.bgrpkey_handshake' > + adapter->securitypriv. > + bgrpkey_handshake = > > WARNING: Avoid multiple line dereference - prefer > 'adapter->securitypriv.PrivacyAlgrthm' > + adapter->securitypriv. > + PrivacyAlgrthm; > > WARNING: Avoid multiple line dereference - prefer 'ptarget_sta->x_UncstKey' > + memset((u8 *)_sta-> > + x_UncstKey, > > WARNING: Avoid multiple line dereference - prefer 'ptarget_sta->tkiprxmickey' > + memset((u8 *)_sta-> > + tkiprxmickey, > > WARNING: Avoid multiple line dereference - prefer 'ptarget_sta->tkiptxmickey' > + memset((u8 *)_sta-> > + tkiptxmickey, > > WARNING: Avoid multiple line dereference - prefer 'ptarget_sta->txpn' > + memset((u8 *)_sta-> > + txpn, 0, > > WARNING: Avoid multiple line dereference - prefer 'ptarget_sta->rxpn' > + memset((u8 *)_sta-> > + rxpn, 0, > > WARNING: Avoid multiple line dereference - prefer 'tgt_network->network' > + r8712_get_wlan_bssid_ex_sz(_network-> > +
Re: [PATCH v2 1/6] perf metricgroup: Make find_metric() public with name change
On 4/6/21 3:24 PM, John Garry wrote: > On 02/04/2021 00:16, Ian Rogers wrote: >> On Thu, Mar 25, 2021 at 3:38 AM John Garry wrote: >>> >>> Function find_metric() is required for the metric processing in the >>> pmu-events testcase, so make it public. Also change the name to include >>> "metricgroup". >> >> Would it make more sense as "pmu_events_map__find_metric" ? >> > > So all functions apart from one in metricgroup.h are named metricgroup__XXX, > so I was trying to keep this style - apart from the double-underscore (which > can be remedied). > > Personally I don't think pmu_events_map__find_metric name fits with that > convention. I agree, most of the functions in metricgroup.c named as metricgroup__xxx. May be something like metricgroup__find_metric will be better. Thanks, Kajol Jain > > Thanks, > John > >> Thanks, >> Ian >> >>> Signed-off-by: John Garry >>> --- >>> tools/perf/util/metricgroup.c | 5 +++-- >>> tools/perf/util/metricgroup.h | 3 ++- >>> 2 files changed, 5 insertions(+), 3 deletions(-) >>> >>> diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c >>> index 6acb44ad439b..71a13406e0bd 100644 >>> --- a/tools/perf/util/metricgroup.c >>> +++ b/tools/perf/util/metricgroup.c >>> @@ -900,7 +900,8 @@ static int __add_metric(struct list_head *metric_list, >>> (match_metric(__pe->metric_group, __metric) || \ >>> match_metric(__pe->metric_name, __metric))) >>> >>> -static struct pmu_event *find_metric(const char *metric, struct >>> pmu_events_map *map) >>> +struct pmu_event *metrcgroup_find_metric(const char *metric, >>> + struct pmu_events_map *map) >>> { >>> struct pmu_event *pe; >>> int i; >>> @@ -985,7 +986,7 @@ static int __resolve_metric(struct metric *m, >>> struct expr_id *parent; >>> struct pmu_event *pe; >>> >>> - pe = find_metric(cur->key, map); >>> + pe = metrcgroup_find_metric(cur->key, map); >>> if (!pe) >>> continue; >>> >>> diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h >>> index ed1b9392e624..1674c6a36d74 100644 >>> --- a/tools/perf/util/metricgroup.h >>> +++ b/tools/perf/util/metricgroup.h >>> @@ -44,7 +44,8 @@ int metricgroup__parse_groups(const struct option *opt, >>> bool metric_no_group, >>> bool metric_no_merge, >>> struct rblist *metric_events); >>> - >>> +struct pmu_event *metrcgroup_find_metric(const char *metric, >>> + struct pmu_events_map *map); >>> int metricgroup__parse_groups_test(struct evlist *evlist, >>> struct pmu_events_map *map, >>> const char *str, >>> -- >>> 2.26.2 >>> >> . >> >
Re: [PATCH] tty: n_gsm: check error while registering tty devices
On 07. 04. 21, 4:16, Hillf Danton wrote: Add the error path for registering tty devices and roll back in case of error in bid to avoid the UAF like the below one reported. [ cut here ] refcount_t: underflow; use-after-free. WARNING: CPU: 1 PID: 8923 at lib/refcount.c:28 refcount_warn_saturate+0x1cf/0x210 -origin/lib/refcount.c:28 Modules linked in: CPU: 1 PID: 8923 Comm: executor Not tainted 5.12.0-rc5+ #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:refcount_warn_saturate+0x1cf/0x210 -origin/lib/refcount.c:28 Code: 4f ff ff ff e8 32 fa b5 fe 48 c7 c7 3d f8 f6 86 e8 d6 ab c6 fe c6 05 7c 34 67 04 01 48 c7 c7 68 f8 6d 86 31 c0 e8 81 2e 9d fe <0f> 0b e9 22 ff ff ff e8 05 fa b5 fe 48 c7 c7 3e f8 f6 86 e8 a9 ab RSP: 0018:c90001633c60 EFLAGS: 00010246 RAX: 15d08b2e34b77800 RBX: 0003 RCX: 88804c056c80 RDX: RSI: RDI: RBP: 0003 R08: 813767aa R09: 0001 R10: 0001 R11: 88804c056c80 R12: 888040b7d000 R13: 88804c206938 R14: 88804c206900 R15: 888041b18488 FS: 022c9940() GS:88807ec0() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7f9f9b122008 CR3: 44b4b000 CR4: 00750ee0 PKRU: 5554 Call Trace: __refcount_sub_and_test -origin/./include/linux/refcount.h:283 [inline] __refcount_dec_and_test -origin/./include/linux/refcount.h:315 [inline] refcount_dec_and_test -origin/./include/linux/refcount.h:333 [inline] kref_put -origin/./include/linux/kref.h:64 [inline] kobject_put+0x17b/0x180 -origin/lib/kobject.c:753 cdev_del+0x4b/0x50 -origin/fs/char_dev.c:597 tty_unregister_device+0x99/0xd0 -origin/drivers/tty/tty_io.c:3343 gsmld_detach_gsm -origin/drivers/tty/n_gsm.c:2409 [inline] gsmld_close+0x6c/0x140 -origin/drivers/tty/n_gsm.c:2478 tty_ldisc_close -origin/drivers/tty/tty_ldisc.c:488 [inline] tty_ldisc_kill -origin/drivers/tty/tty_ldisc.c:636 [inline] tty_ldisc_release+0x1b6/0x400 -origin/drivers/tty/tty_ldisc.c:809 tty_release_struct+0x19/0xb0 -origin/drivers/tty/tty_io.c:1714 tty_release+0x9ad/0xa00 -origin/drivers/tty/tty_io.c:1885 Yes, the fix makes sense. But could you elaborate in the commit log when this happens? I only wonder how real this is. I assume you inject faults to allocations? Reported-and-tested-by: Hao Sun Cc: Jiri Slaby Use my MAINTAINERS e-mail please. Signed-off-by: Hillf Danton --- --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2384,8 +2384,18 @@ static int gsmld_attach_gsm(struct tty_s /* Don't register device 0 - this is the control channel and not a usable tty interface */ base = mux_num_to_base(gsm); /* Base for this MUX */ - for (i = 1; i < NUM_DLCI; i++) - tty_register_device(gsm_tty_driver, base + i, NULL); + for (i = 1; i < NUM_DLCI; i++) { + struct device *dev; + + dev = tty_register_device(gsm_tty_driver, + base + i, NULL); + if (IS_ERR(dev)) { + for (i--; i >= 1; i--) + tty_unregister_device(gsm_tty_driver, + base + i); + return PTR_ERR(dev); + } + } } return ret; } -- thanks, -- js suse labs
Re: [RESEND PATCH] staging: emxx_udc: Ending line with argument
On Tue, Apr 06, 2021 at 09:00:07PM +0100, Beatriz Martins de Carvalho wrote: > > Em 06/04/21 20:36, Greg KH escreveu: > > On Tue, Apr 06, 2021 at 08:34:09PM +0100, Beatriz Martins de Carvalho wrote: > > > Cleans up check of "Lines should not end with a '('" > > > with argument present in next line in file emxx_udc.c > > > > > > Signed-off-by: Beatriz Martins de Carvalho > > > > > > --- > > > drivers/staging/emxx_udc/emxx_udc.c | 11 --- > > > 1 file changed, 4 insertions(+), 7 deletions(-) > > Why is this a [RESEND] ? > > > > What happened to the first version? > Sorry, I didn't receive your review, and in kernelnewbies tutorial, they say > if not receive a response, may have missed the patch, so I resent it. Do you have a pointer to your previous patch in the lore.kernel.org archives anywhere? I can't seem to find it. > > Also, your subject is odd, please look at the documentation for how to > > write good subject lines for patches. > > Yes, I know. It was my second patch, and I was learning, and when I resent > it, I didn't know if I can change the subject. Of course you can always fix up things you know you did incorrectly, don't make others review stuff that you know is wrong, that just wastes everyone's time. thanks, greg k-h
Re: [RESEND PATCH v5 1/2] bio: limit bio max size
On Wed, Apr 07, 2021 at 02:06:33PM +0900, Changheun Lee wrote: > > On Wed, Apr 07, 2021 at 09:16:12AM +0900, Changheun Lee wrote: > > > > On Tue, Apr 06, 2021 at 10:31:28AM +0900, Changheun Lee wrote: > > > > > > bio size can grow up to 4GB when muli-page bvec is enabled. > > > > > > but sometimes it would lead to inefficient behaviors. > > > > > > in case of large chunk direct I/O, - 32MB chunk read in user space - > > > > > > all pages for 32MB would be merged to a bio structure if the pages > > > > > > physical addresses are contiguous. it makes some delay to submit > > > > > > until merge complete. bio max size should be limited to a proper > > > > > > size. > > > > > > > > > > > > When 32MB chunk read with direct I/O option is coming from > > > > > > userspace, > > > > > > kernel behavior is below now in do_direct_IO() loop. it's timeline. > > > > > > > > > > > > | bio merge for 32MB. total 8,192 pages are merged. > > > > > > | total elapsed time is over 2ms. > > > > > > |-- ... --->| > > > > > > | 8,192 pages > > > > > > merged a bio. > > > > > > | at this time, > > > > > > first bio submit is done. > > > > > > | 1 bio is split > > > > > > to 32 read request and issue. > > > > > > |---> > > > > > > |---> > > > > > >|---> > > > > > > .. > > > > > > > > > > > > |---> > > > > > > > > > > > > |--->| > > > > > > total 19ms elapsed to complete 32MB read > > > > > > done from device. | > > > > > > > > > > > > If bio max size is limited with 1MB, behavior is changed below. > > > > > > > > > > > > | bio merge for 1MB. 256 pages are merged for each bio. > > > > > > | total 32 bio will be made. > > > > > > | total elapsed time is over 2ms. it's same. > > > > > > | but, first bio submit timing is fast. about 100us. > > > > > > |--->|--->|--->|---> ... -->|--->|--->|--->|--->| > > > > > > | 256 pages merged a bio. > > > > > > | at this time, first bio submit is done. > > > > > > | and 1 read request is issued for 1 bio. > > > > > > |---> > > > > > >|---> > > > > > > |---> > > > > > > .. > > > > > > |---> > > > > > > |--->| > > > > > > total 17ms elapsed to complete 32MB read done from device. | > > > > > > > > > > > > As a result, read request issue timing is faster if bio max size is > > > > > > limited. > > > > > > Current kernel behavior with multipage bvec, super large bio can be > > > > > > created. > > > > > > And it lead to delay first I/O request issue. > > > > > > > > > > > > Signed-off-by: Changheun Lee > > > > > > --- > > > > > > block/bio.c| 13 - > > > > > > include/linux/bio.h| 2 +- > > > > > > include/linux/blkdev.h | 3 +++ > > > > > > 3 files changed, 16 insertions(+), 2 deletions(-) > > > > > > > > > > > > diff --git a/block/bio.c b/block/bio.c > > > > > > index 1f2cc1fbe283..c528e1f944c7 100644 > > > > > > --- a/block/bio.c > > > > > > +++ b/block/bio.c > > > > > > @@ -287,6 +287,17 @@ void bio_init(struct bio *bio, struct bio_vec > > > > > > *table, > > > > > > } > > > > > > EXPORT_SYMBOL(bio_init); > > > > > > > > > > > > +unsigned int bio_max_size(struct bio *bio) > > > > > > +{ > > > > > > + struct request_queue *q = bio->bi_disk->queue; > > > > > > + > > > > > > + if (blk_queue_limit_bio_size(q)) > > > > > > + return blk_queue_get_max_sectors(q, bio_op(bio)) > > > > > > + << SECTOR_SHIFT; > > > > > > + > > > > > > + return UINT_MAX; > > > > > > +} > > > > > > + > > > > > > /** > > > > > > * bio_reset - reinitialize a bio > > > > > > * @bio: bio to reset > > > > > > @@ -877,7 +888,7 @@ bool __bio_try_merge_page(struct bio *bio, > > > > > > struct page *page, > > > > > > struct bio_vec *bv = >bi_io_vec[bio->bi_vcnt - 1]; > > > > > > > > > > > > if (page_is_mergeable(bv, page, len, off, same_page)) { > > > > > > - if (bio->bi_iter.bi_size > UINT_MAX - len) { > > > > > > + if (bio->bi_iter.bi_size > bio_max_size(bio) - > > > > > > len) { > > > > > > *same_page = false; > > > > > > return false; > > > > > >
[PATCH 05/20] kbuild: scripts/install.sh: prepare for arch-specific bootloaders
Despite the last release of LILO being in 2015, it seems that it is still the default x86 bootloader and wants to be called to "install" the new kernel image when it has been replaced on the disk. To allow arch-specific programs like this to be called in future changes, move the logic to an arch-specific test now. Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 19 --- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 92d0d2ade414..2adcb993efa2 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -54,10 +54,15 @@ install "$2" "$4"/vmlinuz install "$3" "$4"/System.map sync -if [ -x /sbin/lilo ]; then - /sbin/lilo -elif [ -x /etc/lilo/install ]; then - /etc/lilo/install -else - echo "Cannot find LILO." -fi +# Some architectures like to call specific bootloader "helper" programs: +case "${ARCH}" in + x86) + if [ -x /sbin/lilo ]; then + /sbin/lilo + elif [ -x /etc/lilo/install ]; then + /etc/lilo/install + else + echo "Cannot find LILO." + fi + ;; +esac -- 2.31.1
[PATCH 14/20] kbuild: nios2: use common install script
The common scripts/install.sh script will now work for nios2, all that is needed is to add it to the list of arches that do not put the version number in the installed file name. With that we can remove the nios2-only version of the install script. Cc: Ley Foon Tan Signed-off-by: Greg Kroah-Hartman --- arch/nios2/boot/Makefile | 2 +- arch/nios2/boot/install.sh | 52 -- scripts/install.sh | 2 +- 3 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 arch/nios2/boot/install.sh diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile index 37dfc7e584bc..b8d8a3be156a 100644 --- a/arch/nios2/boot/Makefile +++ b/arch/nios2/boot/Makefile @@ -32,4 +32,4 @@ $(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ install: - sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" + sh $(srctree)/scripts/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" diff --git a/arch/nios2/boot/install.sh b/arch/nios2/boot/install.sh deleted file mode 100644 index 3cb3f468bc51.. --- a/arch/nios2/boot/install.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for nios2 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo - -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/vmlinuz -cp $3 $4/System.map - -sync diff --git a/scripts/install.sh b/scripts/install.sh index a61a5ce28cad..407ffa65062c 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -66,7 +66,7 @@ fi # Some architectures name their files based on version number, and # others do not. Call out the ones that do not to make it obvious. case "${ARCH}" in - ia64 | m68k | x86) + ia64 | m68k | nios2 | x86) version="" ;; *) -- 2.31.1
[PATCH 13/20] kbuild: nds32: convert to use the common install scripts
It seems that no one ever checked in the nds32 install script so trying to build a nds32 kernel would never quite work properly as 'make install' would fail to run. Fix that up by having nds32 call the common install.sh script. Cc: Nick Hu Cc: Greentime Hu Cc: Vincent Chen Signed-off-by: Greg Kroah-Hartman --- arch/nds32/boot/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/nds32/boot/Makefile b/arch/nds32/boot/Makefile index c4cc0c2689f7..8371e02f6091 100644 --- a/arch/nds32/boot/Makefile +++ b/arch/nds32/boot/Makefile @@ -8,9 +8,9 @@ $(obj)/Image.gz: $(obj)/Image FORCE $(call if_changed,gzip) install: $(obj)/Image - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh $(KERNELRELEASE) \ $(obj)/Image System.map "$(INSTALL_PATH)" zinstall: $(obj)/Image.gz - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh $(KERNELRELEASE) \ $(obj)/Image.gz System.map "$(INSTALL_PATH)" -- 2.31.1
[PATCH 12/20] kbuild: m68k: use common install script
The common scripts/install.sh script will now work for m68k, all that is needed is to add it to the list of arches that do not put the version number in the installed file name. With that we can remove the m68k-only version of the install script. Cc: Geert Uytterhoeven Cc: linux-m...@lists.linux-m68k.org Signed-off-by: Greg Kroah-Hartman --- arch/m68k/Makefile | 2 +- arch/m68k/install.sh | 52 scripts/install.sh | 2 +- 3 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 arch/m68k/install.sh diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index ea14f2046fb4..e56abf79c313 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -143,4 +143,4 @@ archheaders: $(Q)$(MAKE) $(build)=arch/m68k/kernel/syscalls all install: - sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" + sh $(srctree)/scripts/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" diff --git a/arch/m68k/install.sh b/arch/m68k/install.sh deleted file mode 100644 index 57d640d4382c.. --- a/arch/m68k/install.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for m68k architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo - -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/vmlinuz -cp $3 $4/System.map - -sync diff --git a/scripts/install.sh b/scripts/install.sh index b6ca2a0f0983..a61a5ce28cad 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -66,7 +66,7 @@ fi # Some architectures name their files based on version number, and # others do not. Call out the ones that do not to make it obvious. case "${ARCH}" in - ia64 | x86) + ia64 | m68k | x86) version="" ;; *) -- 2.31.1
[PATCH 11/20] kbuild: ia64: use common install script
The common scripts/install.sh script will now work for ia64, all that is needed is to add the compressed image type to it. So add that file type check and the ability to call /usr/sbin/elilo after copying the kernel. With that we can remove the ia64-only version of the file. Cc: linux-i...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/ia64/Makefile | 2 +- arch/ia64/install.sh | 40 scripts/install.sh | 8 +++- 3 files changed, 8 insertions(+), 42 deletions(-) delete mode 100644 arch/ia64/install.sh diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 467b7e7f967c..19e20e99f487 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -77,7 +77,7 @@ archheaders: CLEAN_FILES += vmlinux.gz install: vmlinux.gz - sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" + sh $(srctree)/scripts/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" define archhelp echo '* compressed - Build compressed kernel image' diff --git a/arch/ia64/install.sh b/arch/ia64/install.sh deleted file mode 100644 index 0e932f5dcd1a.. --- a/arch/ia64/install.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -# -# arch/ia64/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for ia64 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo - -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/vmlinuz -cp $3 $4/System.map - -test -x /usr/sbin/elilo && /usr/sbin/elilo diff --git a/scripts/install.sh b/scripts/install.sh index 73067b535ea0..b6ca2a0f0983 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -52,6 +52,7 @@ if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi base=$(basename "$2") if [ "$base" = "bzImage" ] || [ "$base" = "Image.gz" ] || + [ "$base" = "vmlinux.gz" ] || [ "$base" = "zImage" ] ; then # Compressed install echo "Installing compressed kernel" @@ -65,7 +66,7 @@ fi # Some architectures name their files based on version number, and # others do not. Call out the ones that do not to make it obvious. case "${ARCH}" in - x86) + ia64 | x86) version="" ;; *) @@ -86,6 +87,11 @@ case "${ARCH}" in echo "You have to install it yourself" fi ;; + ia64) + if [ -x /usr/sbin/elilo ]; then + /usr/sbin/elilo + fi + ;; x86) if [ -x /sbin/lilo ]; then /sbin/lilo -- 2.31.1
[PATCH 10/20] kbuild: arm: use common install script
The common scripts/install.sh script will now work for arm, all that is needed is to add the compressed image type to it. So add that file type check and the ability to call /sbin/loadmap after copying the kernel. With that we can remove the arm-only version of the file. Cc: Russell King Cc: Greg Kroah-Hartman Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/Makefile | 6 ++-- arch/arm/boot/install.sh | 66 scripts/install.sh | 10 +- 3 files changed, 12 insertions(+), 70 deletions(-) delete mode 100644 arch/arm/boot/install.sh diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 0b3cd7a33a26..053187f0b714 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -104,15 +104,15 @@ initrd: (echo You must specify INITRD; exit -1) install: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh "$(KERNELRELEASE)" \ $(obj)/Image System.map "$(INSTALL_PATH)" zinstall: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh "$(KERNELRELEASE)" \ $(obj)/zImage System.map "$(INSTALL_PATH)" uinstall: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh "$(KERNELRELEASE)" \ $(obj)/uImage System.map "$(INSTALL_PATH)" subdir-:= bootp compressed dts diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh deleted file mode 100644 index 2a45092a40e3.. --- a/arch/arm/boot/install.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# -# arch/arm/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# Adapted from code in arch/i386/boot/install.sh by Russell King -# -# "make install" script for arm architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -if [ "$(basename $2)" = "zImage" ]; then -# Compressed install - echo "Installing compressed kernel" - base=vmlinuz -else -# Normal install - echo "Installing normal kernel" - base=vmlinux -fi - -if [ -f $4/$base-$1 ]; then - mv $4/$base-$1 $4/$base-$1.old -fi -cat $2 > $4/$base-$1 - -# Install system map file -if [ -f $4/System.map-$1 ]; then - mv $4/System.map-$1 $4/System.map-$1.old -fi -cp $3 $4/System.map-$1 - -if [ -x /sbin/loadmap ]; then - /sbin/loadmap -else - echo "You have to install it yourself" -fi diff --git a/scripts/install.sh b/scripts/install.sh index 9c8a22d96255..73067b535ea0 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -51,7 +51,8 @@ if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi base=$(basename "$2") if [ "$base" = "bzImage" ] || - [ "$base" = "Image.gz" ] ; then + [ "$base" = "Image.gz" ] || + [ "$base" = "zImage" ] ; then # Compressed install echo "Installing compressed kernel" base=vmlinuz @@ -78,6 +79,13 @@ sync # Some architectures like to call specific bootloader "helper" programs: case "${ARCH}" in + arm) + if [ -x /sbin/loadmap ]; then + /sbin/loadmap + else + echo "You have to install it yourself" + fi + ;; x86) if [ -x /sbin/lilo ]; then /sbin/lilo -- 2.31.1
[PATCH 09/20] kbuild: arm64: use common install script
The common scripts/install.sh script will now work for arm65, no changes needed so convert the arm64 boot Makefile to call it instead of the arm64-only version of the file and remove the now unused file. Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/Makefile | 4 +-- arch/arm64/boot/install.sh | 60 -- 2 files changed, 2 insertions(+), 62 deletions(-) delete mode 100644 arch/arm64/boot/install.sh diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index cd3414898d10..08c56332dde2 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -37,9 +37,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE $(call if_changed,lzo) install: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh $(KERNELRELEASE) \ $(obj)/Image System.map "$(INSTALL_PATH)" zinstall: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh $(KERNELRELEASE) \ $(obj)/Image.gz System.map "$(INSTALL_PATH)" diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh deleted file mode 100644 index d91e1f022573.. --- a/arch/arm64/boot/install.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -# -# arch/arm64/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# Adapted from code in arch/i386/boot/install.sh by Russell King -# -# "make install" script for the AArch64 Linux port -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -if [ "$(basename $2)" = "Image.gz" ]; then -# Compressed install - echo "Installing compressed kernel" - base=vmlinuz -else -# Normal install - echo "Installing normal kernel" - base=vmlinux -fi - -if [ -f $4/$base-$1 ]; then - mv $4/$base-$1 $4/$base-$1.old -fi -cat $2 > $4/$base-$1 - -# Install system map file -if [ -f $4/System.map-$1 ]; then - mv $4/System.map-$1 $4/System.map-$1.old -fi -cp $3 $4/System.map-$1 -- 2.31.1
[PATCH 07/20] kbuild: scripts/install.sh: allow for the version number
Some architectures put the version number by default at the end of the files that are copied, so add support for this to be set by arch type. Odds are one day we should change this for x86, but let's not break anyone's systems just yet. Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 72dc4c81013e..934619f81119 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -60,8 +60,19 @@ else base=vmlinux fi -install "$2" "$4"/"$base" -install "$3" "$4"/System.map +# Some architectures name their files based on version number, and +# others do not. Call out the ones that do not to make it obvious. +case "${ARCH}" in + x86) + version="" + ;; + *) + version="-${1}" + ;; +esac + +install "$2" "$4"/"$base""$version" +install "$3" "$4"/System.map"$version" sync # Some architectures like to call specific bootloader "helper" programs: -- 2.31.1
[PATCH 08/20] kbuild: riscv: use common install script
The common scripts/install.sh script will now work for riscv, all that is needed is to add the compressed image type to it. So add that file type check and remove the riscv-only version of the file. Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: linux-ri...@lists.infradead.org Signed-off-by: Greg Kroah-Hartman --- arch/riscv/boot/Makefile | 4 +-- arch/riscv/boot/install.sh | 60 -- scripts/install.sh | 3 +- 3 files changed, 4 insertions(+), 63 deletions(-) delete mode 100644 arch/riscv/boot/install.sh diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile index 03404c84f971..4ba33aec4ccb 100644 --- a/arch/riscv/boot/Makefile +++ b/arch/riscv/boot/Makefile @@ -47,9 +47,9 @@ $(obj)/loader.bin: $(obj)/loader FORCE $(call if_changed,objcopy) install: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh $(KERNELRELEASE) \ $(obj)/Image System.map "$(INSTALL_PATH)" zinstall: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh $(KERNELRELEASE) \ $(obj)/Image.gz System.map "$(INSTALL_PATH)" diff --git a/arch/riscv/boot/install.sh b/arch/riscv/boot/install.sh deleted file mode 100644 index 18c39159c0ff.. --- a/arch/riscv/boot/install.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -# -# arch/riscv/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# Adapted from code in arch/i386/boot/install.sh by Russell King -# -# "make install" script for the RISC-V Linux port -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -if [ "$(basename $2)" = "Image.gz" ]; then -# Compressed install - echo "Installing compressed kernel" - base=vmlinuz -else -# Normal install - echo "Installing normal kernel" - base=vmlinux -fi - -if [ -f $4/$base-$1 ]; then - mv $4/$base-$1 $4/$base-$1.old -fi -cat $2 > $4/$base-$1 - -# Install system map file -if [ -f $4/System.map-$1 ]; then - mv $4/System.map-$1 $4/System.map-$1.old -fi -cp $3 $4/System.map-$1 diff --git a/scripts/install.sh b/scripts/install.sh index 934619f81119..9c8a22d96255 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -50,7 +50,8 @@ if [ -x ~/bin/"${INSTALLKERNEL}" ]; then exec ~/bin/"${INSTALLKERNEL}" "$@"; fi if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi base=$(basename "$2") -if [ "$base" = "bzImage" ]; then +if [ "$base" = "bzImage" ] || + [ "$base" = "Image.gz" ] ; then # Compressed install echo "Installing compressed kernel" base=vmlinuz -- 2.31.1
[PATCH 20/20] kbuild: scripts/install.sh: update documentation
Add a proper SPDX line and document the install.sh file a lot better, explaining exactly what it does, and update the copyright notice and provide a better message about the lack of LILO being present or not as really, no one should be using that anymore... Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 225b19bbbfa6..dd86fb9971e9 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,14 +1,14 @@ #!/bin/sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. +# SPDX-License-Identifier: GPL-2.0 # # Copyright (C) 1995 by Linus Torvalds +# Copyright (C) 2021 Greg Kroah-Hartman # # Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# Adapted from code in arch/i386/boot/install.sh by Russell King +# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy # -# "make install" script for i386 architecture +# "make install" script for Linux to be used by all architectures. # # Arguments: # $1 - kernel version @@ -16,6 +16,26 @@ # $3 - kernel map file # $4 - default install path (blank if root directory) # +# Installs the built kernel image and map and symbol file in the specified +# install location. If no install path is selected, the files will be placed +# in the root directory. +# +# The name of the kernel image will be "vmlinux-VERSION" for uncompressed +# kernels or "vmlinuz-VERSION' for compressed kernels. +# +# The kernel map file will be named "System.map-VERSION" +# +# Note, not all architectures seem to like putting the VERSION number in the +# file name, see below in the script for a list of those that do not. For +# those that do not the "-VERSION" will not be present in the file name. +# +# If there is currently a kernel image or kernel map file present with the name +# of the file to be copied to the location, it will be renamed to contain a +# ".old" suffix. +# +# If ~/bin/${INSTALLKERNEL} or /sbin/${INSTALLKERNEL} is executable, execution +# will be passed to that program instead of this one to allow for distro or +# system specific installation scripts to be used. verify () { if [ ! -f "$1" ]; then @@ -45,7 +65,6 @@ verify "$2" verify "$3" # User may have a custom install script - if [ -x ~/bin/"${INSTALLKERNEL}" ]; then exec ~/bin/"${INSTALLKERNEL}" "$@"; fi if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi @@ -111,7 +130,7 @@ case "${ARCH}" in elif [ -x /etc/lilo/install ]; then /etc/lilo/install else - echo "Cannot find LILO." + echo "Cannot find LILO, ensure your bootloader knows of the new kernel image." fi ;; esac -- 2.31.1
[PATCH 19/20] kbuild: sparc: use common install script
The common scripts/install.sh script will now work for sparc, all that is needed is to add it to the list of arches that do not put the version number in the installed file name. With that we can remove the sparc-only version of the install script. Cc: "David S. Miller" Cc: sparcli...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/sparc/boot/Makefile | 2 +- arch/sparc/boot/install.sh | 50 -- scripts/install.sh | 2 +- 3 files changed, 2 insertions(+), 52 deletions(-) delete mode 100644 arch/sparc/boot/install.sh diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index 380e2b018992..952f8e7a40ec 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile @@ -72,5 +72,5 @@ $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE $(call if_changed,piggy) install: - sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/zImage \ + sh $(srctree)/scripts/install.sh $(KERNELRELEASE) $(obj)/zImage \ System.map "$(INSTALL_PATH)" diff --git a/arch/sparc/boot/install.sh b/arch/sparc/boot/install.sh deleted file mode 100644 index b32851eae693.. --- a/arch/sparc/boot/install.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for SPARC architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo - -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/vmlinuz -cp $3 $4/System.map diff --git a/scripts/install.sh b/scripts/install.sh index 67c0a5f74af2..225b19bbbfa6 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -67,7 +67,7 @@ fi # Some architectures name their files based on version number, and # others do not. Call out the ones that do not to make it obvious. case "${ARCH}" in - ia64 | m68k | nios2 | powerpc | x86) + ia64 | m68k | nios2 | powerpc | sparc | x86) version="" ;; *) -- 2.31.1
[PATCH 18/20] kbuild: sh: remove unused install script
The sh arch has a install.sh script, but no Makefile actually calls it. Remove it to keep anyone from accidentally calling it in the future. Cc: Yoshinori Sato Cc: Rich Felker Cc: linux...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/sh/boot/compressed/install.sh | 56 -- 1 file changed, 56 deletions(-) delete mode 100644 arch/sh/boot/compressed/install.sh diff --git a/arch/sh/boot/compressed/install.sh b/arch/sh/boot/compressed/install.sh deleted file mode 100644 index f9f41818b17e.. --- a/arch/sh/boot/compressed/install.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh -# -# arch/sh/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# Adapted from code in arch/i386/boot/install.sh by Russell King -# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy -# -# "make install" script for sh architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -# User may have a custom install script - -if [ -x /sbin/${INSTALLKERNEL} ]; then - exec /sbin/${INSTALLKERNEL} "$@" -fi - -if [ "$2" = "zImage" ]; then -# Compressed install - echo "Installing compressed kernel" - if [ -f $4/vmlinuz-$1 ]; then -mv $4/vmlinuz-$1 $4/vmlinuz.old - fi - - if [ -f $4/System.map-$1 ]; then -mv $4/System.map-$1 $4/System.old - fi - - cat $2 > $4/vmlinuz-$1 - cp $3 $4/System.map-$1 -else -# Normal install - echo "Installing normal kernel" - if [ -f $4/vmlinux-$1 ]; then -mv $4/vmlinux-$1 $4/vmlinux.old - fi - - if [ -f $4/System.map ]; then -mv $4/System.map $4/System.old - fi - - cat $2 > $4/vmlinux-$1 - cp $3 $4/System.map -fi -- 2.31.1
[PATCH 17/20] kbuild: s390: use common install script
The common scripts/install.sh script will now work for s390, no changes needed. So call that instead and delete the s390-only install script. Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Cc: linux-s...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/s390/boot/Makefile | 2 +- arch/s390/boot/install.sh | 30 -- 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 arch/s390/boot/install.sh diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index 41a64b8dce25..5e3058d6e59b 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -71,5 +71,5 @@ $(obj)/startup.a: $(OBJECTS) FORCE $(call if_changed,ar) install: - sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ + sh -x $(srctree)/scripts/install.sh $(KERNELRELEASE) $(obj)/bzImage \ System.map "$(INSTALL_PATH)" diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh deleted file mode 100644 index 515b27a996b3.. --- a/arch/s390/boot/install.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# -# arch/s390x/boot/install.sh -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for s390 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -echo "Warning: '${INSTALLKERNEL}' command not available - additional " \ - "bootloader config required" >&2 -if [ -f $4/vmlinuz-$1 ]; then mv $4/vmlinuz-$1 $4/vmlinuz-$1.old; fi -if [ -f $4/System.map-$1 ]; then mv $4/System.map-$1 $4/System.map-$1.old; fi - -cat $2 > $4/vmlinuz-$1 -cp $3 $4/System.map-$1 -- 2.31.1
[PATCH 16/20] kbuild: powerpc: use common install script
The common scripts/install.sh script will now work for powerpc, all that is needed is to add it to the list of arches that do not put the version number in the installed file name. After the kernel is installed, powerpc also likes to install a few random files, so provide the ability to do that as well. With that we can remove the powerpc-only version of the install script. Cc: Michael Ellerman Cc: linuxppc-...@lists.ozlabs.org Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/boot/Makefile | 4 +-- arch/powerpc/boot/install.sh | 55 scripts/install.sh | 14 - 3 files changed, 15 insertions(+), 58 deletions(-) delete mode 100644 arch/powerpc/boot/install.sh diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 2b8da923ceca..bbfcbd33e0b7 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -442,11 +442,11 @@ $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) # Only install the vmlinux install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) - sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" + sh -x $(srctree)/scripts/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" # Install the vmlinux and other built boot targets. zInstall: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) - sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ + sh -x $(srctree)/scripts/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ PHONY += install zInstall diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh deleted file mode 100644 index b6a256bc96ee.. --- a/arch/powerpc/boot/install.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Blatantly stolen from in arch/i386/boot/install.sh by Dave Hansen -# -# "make install" script for ppc64 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# $5 and more - kernel boot files; zImage*, uImage, cuImage.*, etc. -# - -# Bail with error code if anything goes wrong -set -e - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - -# this should work for both the pSeries zImage and the iSeries vmlinux.sm -image_name=`basename $2` - -if [ -f $4/$image_name ]; then - mv $4/$image_name $4/$image_name.old -fi - -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old -fi - -cat $2 > $4/$image_name -cp $3 $4/System.map - -# Copy all the bootable image files -path=$4 -shift 4 -while [ $# -ne 0 ]; do - image_name=`basename $1` - if [ -f $path/$image_name ]; then - mv $path/$image_name $path/$image_name.old - fi - cat $1 > $path/$image_name - shift -done; diff --git a/scripts/install.sh b/scripts/install.sh index e0ffb95737d4..67c0a5f74af2 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -67,7 +67,7 @@ fi # Some architectures name their files based on version number, and # others do not. Call out the ones that do not to make it obvious. case "${ARCH}" in - ia64 | m68k | nios2 | x86) + ia64 | m68k | nios2 | powerpc | x86) version="" ;; *) @@ -93,6 +93,18 @@ case "${ARCH}" in /usr/sbin/elilo fi ;; + powerpc) + # powerpc installation can list other boot targets after the + # install path that should be copied to the correct location + path=$4 + shift 4 + while [ $# -ne 0 ]; do + image_name=$(basename "$1") + install "$1" "$path"/"$image_name" + shift + done; + sync + ;; x86) if [ -x /sbin/lilo ]; then /sbin/lilo -- 2.31.1
[PATCH 15/20] kbuild: parisc: use common install script
The common scripts/install.sh script will now work for parisc, all that is needed is to add the compressed image type to it. So add that file type check, and then we can remove the two different copies of the parisc install.sh script that were only different by one line and have the arch call the common install script. Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: linux-par...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/parisc/Makefile| 4 +-- arch/parisc/boot/Makefile | 2 +- arch/parisc/boot/install.sh | 65 arch/parisc/install.sh | 66 - scripts/install.sh | 1 + 5 files changed, 4 insertions(+), 134 deletions(-) delete mode 100644 arch/parisc/boot/install.sh delete mode 100644 arch/parisc/install.sh diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 7d9f71aa829a..296d8ab8e2aa 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -164,10 +164,10 @@ vmlinuz: vmlinux endif install: - $(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh \ $(KERNELRELEASE) vmlinux System.map "$(INSTALL_PATH)" zinstall: - $(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \ + $(CONFIG_SHELL) $(srctree)/scripts/install.sh \ $(KERNELRELEASE) vmlinuz System.map "$(INSTALL_PATH)" CLEAN_FILES+= lifimage diff --git a/arch/parisc/boot/Makefile b/arch/parisc/boot/Makefile index 61f44142cfe1..ad2611929aee 100644 --- a/arch/parisc/boot/Makefile +++ b/arch/parisc/boot/Makefile @@ -17,5 +17,5 @@ $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ install: $(CONFIGURE) $(obj)/bzImage - sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ + sh -x $(srctree)/scripts/install.sh $(KERNELRELEASE) $(obj)/bzImage \ System.map "$(INSTALL_PATH)" diff --git a/arch/parisc/boot/install.sh b/arch/parisc/boot/install.sh deleted file mode 100644 index 8f7c365fad83.. --- a/arch/parisc/boot/install.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/sh -# -# arch/parisc/install.sh, derived from arch/i386/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for i386 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist - -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -n "${INSTALLKERNEL}" ]; then - if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi - if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi -fi - -# Default install - -if [ "$(basename $2)" = "zImage" ]; then -# Compressed install - echo "Installing compressed kernel" - base=vmlinuz -else -# Normal install - echo "Installing normal kernel" - base=vmlinux -fi - -if [ -f $4/$base-$1 ]; then - mv $4/$base-$1 $4/$base-$1.old -fi -cat $2 > $4/$base-$1 - -# Install system map file -if [ -f $4/System.map-$1 ]; then - mv $4/System.map-$1 $4/System.map-$1.old -fi -cp $3 $4/System.map-$1 diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh deleted file mode 100644 index 056d588befdd.. --- a/arch/parisc/install.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# -# arch/parisc/install.sh, derived from arch/i386/boot/install.sh -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1995 by Linus Torvalds -# -# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -# -# "make install" script for i386 architecture -# -# Arguments: -# $1 - kernel version -# $2 - kernel image file -# $3 - kernel map file -# $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo ""
[PATCH 02/20] kbuild: scripts/install.sh: properly quote all variables
A few variables are quoted to handle spaces in directory names, but not all of them. Properly quote everything so that the kernel build can handle working correctly with directory names with spaces. This change makes the script "shellcheck" clean now. Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index d13ec1c38640..c183d6ddd00c 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -33,21 +33,21 @@ verify "$3" # User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi +if [ -x ~/bin/"${INSTALLKERNEL}" ]; then exec ~/bin/"${INSTALLKERNEL}" "$@"; fi +if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi # Default install - same as make zlilo -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old +if [ -f "$4"/vmlinuz ]; then + mv "$4"/vmlinuz "$4"/vmlinuz.old fi -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old +if [ -f "$4"/System.map ]; then + mv "$4"/System.map "$4"/System.old fi -cat $2 > $4/vmlinuz -cp $3 $4/System.map +cat "$2" > "$4"/vmlinuz +cp "$3" "$4"/System.map if [ -x /sbin/lilo ]; then /sbin/lilo -- 2.31.1
[PATCH 06/20] kbuild: scripts/install.sh: handle compressed/uncompressed kernel images
For x86, the default kernel image is compressed, but other architectures allowed both compressed and uncompressed kernel images to be built. Add a test to detect which one this is, and either name the output file "vmlinuz" for a compressed image, or "vmlinux" for an uncompressed image. For x86 this change is a no-op, but other architectures depend on this. Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 2adcb993efa2..72dc4c81013e 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -49,8 +49,18 @@ verify "$3" if [ -x ~/bin/"${INSTALLKERNEL}" ]; then exec ~/bin/"${INSTALLKERNEL}" "$@"; fi if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi -# Default install - same as make zlilo -install "$2" "$4"/vmlinuz +base=$(basename "$2") +if [ "$base" = "bzImage" ]; then + # Compressed install + echo "Installing compressed kernel" + base=vmlinuz +else + # Normal install + echo "Installing normal kernel" + base=vmlinux +fi + +install "$2" "$4"/"$base" install "$3" "$4"/System.map sync -- 2.31.1
[PATCH 04/20] kbuild: scripts/install.sh: call sync before calling the bootloader installer
It's good to ensure that the files are written out before calling the bootloader installer, as other architectures do, so call sync after doing the copying of the kernel and system map files. Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install.sh b/scripts/install.sh index af36c0a82f01..92d0d2ade414 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -52,12 +52,12 @@ if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi # Default install - same as make zlilo install "$2" "$4"/vmlinuz install "$3" "$4"/System.map +sync if [ -x /sbin/lilo ]; then /sbin/lilo elif [ -x /etc/lilo/install ]; then /etc/lilo/install else - sync echo "Cannot find LILO." fi -- 2.31.1
[PATCH 03/20] kbuild: scripts/install.sh: provide a "install" function
Instead of open-coding the "test for file, if present make a backup, then copy the file to the new location" in multiple places, make a single function, install(), to do all of this in one place. Note, this does change the default x86 kernel map file saved name from "System.old" to "System.map.old". This brings it into unification with the other architectures as to what they call their backup file for the kernel map file. As this is a text file, and nothing parses this from a backup file, there should not be any operational differences. Signed-off-by: Greg Kroah-Hartman --- scripts/install.sh | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index c183d6ddd00c..af36c0a82f01 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -27,6 +27,19 @@ verify () { fi } +install () { + install_source=${1} + install_target=${2} + + echo "installing '${install_source}' to '${install_target}'" + + # if the target is already present, move it to a .old filename + if [ -f "${install_target}" ]; then + mv "${install_target}" "${install_target}".old + fi + cat "${install_source}" > "${install_target}" +} + # Make sure the files actually exist verify "$2" verify "$3" @@ -37,17 +50,8 @@ if [ -x ~/bin/"${INSTALLKERNEL}" ]; then exec ~/bin/"${INSTALLKERNEL}" "$@"; fi if [ -x /sbin/"${INSTALLKERNEL}" ]; then exec /sbin/"${INSTALLKERNEL}" "$@"; fi # Default install - same as make zlilo - -if [ -f "$4"/vmlinuz ]; then - mv "$4"/vmlinuz "$4"/vmlinuz.old -fi - -if [ -f "$4"/System.map ]; then - mv "$4"/System.map "$4"/System.old -fi - -cat "$2" > "$4"/vmlinuz -cp "$3" "$4"/System.map +install "$2" "$4"/vmlinuz +install "$3" "$4"/System.map if [ -x /sbin/lilo ]; then /sbin/lilo -- 2.31.1
[PATCH 01/20] kbuild: move x86 install script to scripts/install.sh
To unify the different architecture kernel installation scripts, start out with the one they all were based on, the x86 script. Move it from arch/x86/boot/ into scripts/ so that all architectures can call it in the future. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: x...@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/boot/Makefile| 2 +- {arch/x86/boot => scripts}/install.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {arch/x86/boot => scripts}/install.sh (100%) diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index fe605205b4ce..17c7718c1a4a 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -157,5 +157,5 @@ bzlilo: if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi install: - sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ + sh $(srctree)/scripts/install.sh $(KERNELRELEASE) $(obj)/bzImage \ System.map "$(INSTALL_PATH)" diff --git a/arch/x86/boot/install.sh b/scripts/install.sh similarity index 100% rename from arch/x86/boot/install.sh rename to scripts/install.sh -- 2.31.1
[PATCH 00/20] kbuild: unify the install.sh script usage
Almost every architecture has copied the "install.sh" script that originally came with i386, and modified it in very tiny ways. This patch series unifies all of these scripts into one single script to allow people to understand how to correctly install a kernel, and fixes up some issues regarding trying to install a kernel to a path with spaces in it. Note that not all architectures actually seem to have any type of way to install a kernel, they must rely on external scripts or tools which feels odd as everything should be included here in the main repository. I'll work on trying to figure out the missing architecture issues afterward. Note the cc: list here is crazy, due to touching arch-specific code in a number of different arches in the same patch series. I've cc:ed individual arch maintainers on this 00/20 patch, and on their individual arch-specific patch as well, but not the whole thing. thanks, greg k-h Greg Kroah-Hartman (20): kbuild: move x86 install script to scripts/install.sh kbuild: scripts/install.sh: properly quote all variables kbuild: scripts/install.sh: provide a "install" function kbuild: scripts/install.sh: call sync before calling the bootloader installer kbuild: scripts/install.sh: prepare for arch-specific bootloaders kbuild: scripts/install.sh: handle compressed/uncompressed kernel images kbuild: scripts/install.sh: allow for the version number kbuild: riscv: use common install script kbuild: arm64: use common install script kbuild: arm: use common install script kbuild: ia64: use common install script kbuild: m68k: use common install script kbuild: nds32: convert to use the common install scripts kbuild: nios2: use common install script kbuild: parisc: use common install script kbuild: powerpc: use common install script kbuild: s390: use common install script kbuild: sh: remove unused install script kbuild: sparc: use common install script kbuild: scripts/install.sh: update documentation arch/arm/boot/Makefile | 6 +- arch/arm/boot/install.sh | 66 -- arch/arm64/boot/Makefile | 4 +- arch/arm64/boot/install.sh | 60 - arch/ia64/Makefile | 2 +- arch/ia64/install.sh | 40 - arch/m68k/Makefile | 2 +- arch/m68k/install.sh | 52 --- arch/nds32/boot/Makefile | 4 +- arch/nios2/boot/Makefile | 2 +- arch/nios2/boot/install.sh | 52 --- arch/parisc/Makefile | 4 +- arch/parisc/boot/Makefile | 2 +- arch/parisc/boot/install.sh| 65 -- arch/parisc/install.sh | 66 -- arch/powerpc/boot/Makefile | 4 +- arch/powerpc/boot/install.sh | 55 arch/riscv/boot/Makefile | 4 +- arch/riscv/boot/install.sh | 60 - arch/s390/boot/Makefile| 2 +- arch/s390/boot/install.sh | 30 --- arch/sh/boot/compressed/install.sh | 56 arch/sparc/boot/Makefile | 2 +- arch/sparc/boot/install.sh | 50 --- arch/x86/boot/Makefile | 2 +- arch/x86/boot/install.sh | 59 - scripts/install.sh | 136 + 27 files changed, 156 insertions(+), 731 deletions(-) delete mode 100644 arch/arm/boot/install.sh delete mode 100644 arch/arm64/boot/install.sh delete mode 100644 arch/ia64/install.sh delete mode 100644 arch/m68k/install.sh delete mode 100644 arch/nios2/boot/install.sh delete mode 100644 arch/parisc/boot/install.sh delete mode 100644 arch/parisc/install.sh delete mode 100644 arch/powerpc/boot/install.sh delete mode 100644 arch/riscv/boot/install.sh delete mode 100644 arch/s390/boot/install.sh delete mode 100644 arch/sh/boot/compressed/install.sh delete mode 100644 arch/sparc/boot/install.sh delete mode 100644 arch/x86/boot/install.sh create mode 100644 scripts/install.sh base-commit: e49d033bddf5b565044e2abe4241353959bc9120 -- 2.31.1
[PATCH] dmaengine: stm32: Fix rumtime PM imbalance in stm32_dmamux_resume
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error. Signed-off-by: Dinghao Liu --- drivers/dma/stm32-dmamux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c index ef0d0555103d..f9258a63b9c3 100644 --- a/drivers/dma/stm32-dmamux.c +++ b/drivers/dma/stm32-dmamux.c @@ -361,7 +361,7 @@ static int stm32_dmamux_resume(struct device *dev) if (ret < 0) return ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) return ret; -- 2.17.1
Re: [PATCH v7 4/8] dt-bindings: pwm: Support new PWM_STAGGERING_ALLOWED flag
On Tue, Apr 06, 2021 at 06:41:36PM +0200, Clemens Gruber wrote: > Add the flag and corresponding documentation for the new PWM staggering > mode feature. > > Cc: Rob Herring > Signed-off-by: Clemens Gruber For the record, I don't like this and still prefer to make this staggering explicit for the consumer by expanding struct pwm_state with an .offset member to shift the active phase in the period. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | https://www.pengutronix.de/ | signature.asc Description: PGP signature
Bidding invitation
Good Day Sir/Ms, We are pleased to invite you or your company to quote the following item listed below: Product/Model No: A702TH FYNE PRESSURE REGULATOR Model Number: A702TH Qty. 30 units Compulsory,Kindly send your quotation to: qu...@pfizersuppliers.com for immediate approval. Kind Regards, Albert Bourla PFIZER B.V Supply Chain Manager Tel: +31(0)208080 880 ADDRESS: Rivium Westlaan 142, 2909 LD Capelle aan den IJssel, Netherlands
Re: [PATCH v7 2/8] pwm: pca9685: Support hardware readout
On Tue, Apr 06, 2021 at 06:41:34PM +0200, Clemens Gruber wrote: > Implements .get_state to read-out the current hardware state. > > The hardware readout may return slightly different values than those > that were set in apply due to the limited range of possible prescale and > counter register values. > > Also note that although the datasheet mentions 200 Hz as default > frequency when using the internal 25 MHz oscillator, the calculated > period from the default prescaler register setting of 30 is 5079040ns. > > Signed-off-by: Clemens Gruber > --- > Changes since v6: > - Added a comment regarding the division (Suggested by Uwe) > - Rebased > > drivers/pwm/pwm-pca9685.c | 46 +++ > 1 file changed, 46 insertions(+) > > diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c > index 5a2ce97e71fd..d4474c5ff96f 100644 > --- a/drivers/pwm/pwm-pca9685.c > +++ b/drivers/pwm/pwm-pca9685.c > @@ -333,6 +333,51 @@ static int pca9685_pwm_apply(struct pwm_chip *chip, > struct pwm_device *pwm, > return 0; > } > > +static void pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device > *pwm, > + struct pwm_state *state) > +{ > + struct pca9685 *pca = to_pca(chip); > + unsigned long long duty; > + unsigned int val = 0; > + > + /* Calculate (chip-wide) period from prescale value */ > + regmap_read(pca->regmap, PCA9685_PRESCALE, ); > + /* > + * PCA9685_OSC_CLOCK_MHZ is 25, i.e. an integer divider of 1000. > + * The following calculation is therefore only a multiplication > + * and we are not losing precision. > + */ > + state->period = (PCA9685_COUNTER_RANGE * 1000 / PCA9685_OSC_CLOCK_MHZ) * > + (val + 1); > + > + /* The (per-channel) polarity is fixed */ > + state->polarity = PWM_POLARITY_NORMAL; > + > + if (pwm->hwpwm >= PCA9685_MAXCHAN) { > + /* > + * The "all LEDs" channel does not support HW readout > + * Return 0 and disabled for backwards compatibility > + */ > + state->duty_cycle = 0; > + state->enabled = false; > + return; > + } > + > + duty = pca9685_pwm_get_duty(pca, pwm->hwpwm); > + > + state->enabled = !!duty; > + if (!state->enabled) { > + state->duty_cycle = 0; > + return; > + } else if (duty == PCA9685_COUNTER_RANGE) { > + state->duty_cycle = state->period; > + return; > + } > + > + duty *= state->period; > + state->duty_cycle = duty / PCA9685_COUNTER_RANGE; Given that with duty = 0 the chip is still "on" and changing the duty will first complete the currently running period, I'd model duty=0 as enabled. This also simplifies the code a bit, to something like: state->enabled = true; duty = pca9685_pwm_get_duty(pca, pwm->hwpwm); state->duty_cycle = div_round_up(duty * state->period, PCA9685_COUNTER_RANGE); (I'm using round-up here assuming apply uses round-down to get idempotency. In the current patch set state this is wrong however.) > +} > + > static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) > { > struct pca9685 *pca = to_pca(chip); Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | https://www.pengutronix.de/ | signature.asc Description: PGP signature
[PATCH] Input: gpio-keys - fix crash when disabliing GPIO-less buttons
My brain-damaged adjustments to Paul's patch caused crashes in gpio_keys_disable_button() when driver is used in GPIO-less (i.e. purely interrupt-driven) setups, because I mixed together debounce and release timers when they are in fact separate: Unable to handle kernel NULL pointer dereference at virtual address 000c ... PC is at hrtimer_active+0xc/0x98 LR is at hrtimer_try_to_cancel+0x24/0x140 ... [] (hrtimer_active) from [] (hrtimer_try_to_cancel+0x24/0x140) [] (hrtimer_try_to_cancel) from [] (hrtimer_cancel+0x14/0x4c) [] (hrtimer_cancel) from [] (gpio_keys_attr_store_helper+0x1b8/0x1d8 [gpio_keys]) [] (gpio_keys_attr_store_helper [gpio_keys]) from [] (gpio_keys_store_disabled_keys+0x18/0x24 [gpio_keys]) [] (gpio_keys_store_disabled_keys [gpio_keys]) from [] (kernfs_fop_write_iter+0x10c/0x1cc) [] (kernfs_fop_write_iter) from [] (vfs_write+0x2ac/0x404) [] (vfs_write) from [] (ksys_write+0x64/0xdc) [] (ksys_write) from [] (ret_fast_syscall+0x0/0x58) Let's fix it up. Fixes: c9efb0ba281e ("Input: gpio-keys - use hrtimer for software debounce, if possible") Reported-by: Tony Lindgren Signed-off-by: Dmitry Torokhov --- Tony, could you please try this patch and see if it fixes the crash you observed? Thanks! drivers/input/keyboard/gpio_keys.c | 30 +- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index fe8fc76ee22e..8dbf1e69c90a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -125,6 +125,18 @@ static const unsigned long *get_bm_events_by_type(struct input_dev *dev, return (type == EV_KEY) ? dev->keybit : dev->swbit; } +static void gpio_keys_quiesce_key(void *data) +{ + struct gpio_button_data *bdata = data; + + if (!bdata->gpiod) + hrtimer_cancel(>release_timer); + if (bdata->debounce_use_hrtimer) + hrtimer_cancel(>debounce_timer); + else + cancel_delayed_work_sync(>work); +} + /** * gpio_keys_disable_button() - disables given GPIO button * @bdata: button data for button to be disabled @@ -145,12 +157,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) * Disable IRQ and associated timer/work structure. */ disable_irq(bdata->irq); - - if (bdata->debounce_use_hrtimer) - hrtimer_cancel(>release_timer); - else - cancel_delayed_work_sync(>work); - + gpio_keys_quiesce_key(bdata); bdata->disabled = true; } } @@ -492,16 +499,6 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static void gpio_keys_quiesce_key(void *data) -{ - struct gpio_button_data *bdata = data; - - if (bdata->debounce_use_hrtimer) - hrtimer_cancel(>debounce_timer); - else - cancel_delayed_work_sync(>work); -} - static int gpio_keys_setup_key(struct platform_device *pdev, struct input_dev *input, struct gpio_keys_drvdata *ddata, @@ -635,7 +632,6 @@ static int gpio_keys_setup_key(struct platform_device *pdev, } bdata->release_delay = button->debounce_interval; - bdata->debounce_use_hrtimer = true; hrtimer_init(>release_timer, CLOCK_REALTIME, HRTIMER_MODE_REL_HARD); bdata->release_timer.function = gpio_keys_irq_timer; -- 2.31.0.208.g409f899ff0-goog -- Dmitry
Re: [PATCH v2 04/10] tty: tty_jobctrl: Fix coding style issues of block comments
On 06. 04. 21, 13:24, Xiaofei Tan wrote: Fix coding style issues of block comments, reported by checkpatch.pl. Besides, do some expression optimization for the sentenses. Signed-off-by: Xiaofei Tan --- drivers/tty/tty_jobctrl.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index 86070f7..7003b6b 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -204,8 +204,10 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session) spin_lock_irq(>sighand->siglock); if (p->signal->tty == tty) { p->signal->tty = NULL; - /* We defer the dereferences outside fo - the tasklist lock */ + /* +* We defer the dereferences outside of +* the tasklist lock period :). No, I meant "period" as this punctuation mark: . +*/ refs++; } if (!p->signal->leader) { @@ -328,9 +330,11 @@ void disassociate_ctty(int on_exit) */ void no_tty(void) { - /* FIXME: Review locking here. The tty_lock never covered any race - between a new association and proc_clear_tty but possible we need - to protect against this anyway */ + /* +* FIXME: Review locking here. The tty_lock never covered any race +* between a new association and proc_clear_tty but possibly we need +* to protect against this period anyway The same here. +*/ struct task_struct *tsk = current; disassociate_ctty(0); @@ -536,7 +540,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ /* * (tty == real_tty) is a cheap way of * testing if the tty is NOT a master pty. - */ +*/ if (tty == real_tty && current->signal->tty != real_tty) return -ENOTTY; -- js suse labs
[PATCH] mfd: syscon: free the allocated name field of struct regmap_config
From: Limeng The commit 529a1101212a("mfd: syscon: Don't free allocated name for regmap_config") doesn't free the allocated name field of struct regmap_config, but introduce a memory leak. There is another commit 94cc89eb8fa5("regmap: debugfs: Fix handling of name string for debugfs init delays") fixing this debugfs init issue from root cause. With this fixing, the name field in struct regmap_debugfs_node is removed. When initialize debugfs for syscon driver, the name field of struct regmap_config is not used anymore. So, the allocated name field of struct regmap_config is need to be freed directly after regmap initialization to avoid memory leak. Fixes: 529a1101212a("mfd: syscon: Don't free allocated name for regmap_config") Cc: Marc Zyngier Cc: sta...@vger.kernel.org Signed-off-by: Meng Li --- drivers/mfd/syscon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index ca465794ea9c..df5cebb372a5 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -108,6 +108,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) syscon_config.max_register = resource_size() - reg_io_width; regmap = regmap_init_mmio(NULL, base, _config); + kfree(syscon_config.name); if (IS_ERR(regmap)) { pr_err("regmap init failed\n"); ret = PTR_ERR(regmap); @@ -144,7 +145,6 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) regmap_exit(regmap); err_regmap: iounmap(base); - kfree(syscon_config.name); err_map: kfree(syscon); return ERR_PTR(ret); -- 2.17.1
Re: [PATCH v2 8/8] KVM: SVM: Allocate SEV command structures on local stack
Le 07/04/2021 à 00:49, Sean Christopherson a écrit : Use the local stack to "allocate" the structures used to communicate with the PSP. The largest struct used by KVM, sev_data_launch_secret, clocks in at 52 bytes, well within the realm of reasonable stack usage. The smallest structs are a mere 4 bytes, i.e. the pointer for the allocation is larger than the allocation itself. Now that the PSP driver plays nice with vmalloc pointers, putting the data on a virtually mapped stack (CONFIG_VMAP_STACK=y) will not cause explosions. Cc: Brijesh Singh Cc: Tom Lendacky Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/sev.c | 262 +++-- 1 file changed, 96 insertions(+), 166 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 5457138c7347..316fd39c7aef 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -150,35 +150,22 @@ static void sev_asid_free(int asid) static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) { - struct sev_data_decommission *decommission; - struct sev_data_deactivate *data; + struct sev_data_decommission decommission; + struct sev_data_deactivate deactivate; if (!handle) return; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return; - - /* deactivate handle */ - data->handle = handle; + deactivate.handle = handle; /* Guard DEACTIVATE against WBINVD/DF_FLUSH used in ASID recycling */ down_read(_deactivate_lock); - sev_guest_deactivate(data, NULL); + sev_guest_deactivate(, NULL); up_read(_deactivate_lock); - kfree(data); - - decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); - if (!decommission) - return; - /* decommission handle */ - decommission->handle = handle; - sev_guest_decommission(decommission, NULL); - - kfree(decommission); + decommission.handle = handle; + sev_guest_decommission(, NULL); } static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) @@ -216,19 +203,14 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) { - struct sev_data_activate *data; + struct sev_data_activate activate; int asid = sev_get_asid(kvm); int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); - if (!data) - return -ENOMEM; - /* activate ASID on the given handle */ - data->handle = handle; - data->asid = asid; - ret = sev_guest_activate(data, error); - kfree(data); + activate.handle = handle; + activate.asid = asid; + ret = sev_guest_activate(, error); return ret; } @@ -258,7 +240,7 @@ static int sev_issue_cmd(struct kvm *kvm, int id, void *data, int *error) static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) { struct kvm_sev_info *sev = _kvm_svm(kvm)->sev_info; - struct sev_data_launch_start *start; + struct sev_data_launch_start start; struct sev_data_launch_start start = {0, 0, 0, 0, 0, 0, 0}; struct kvm_sev_launch_start params; void *dh_blob, *session_blob; int *error = >error; @@ -270,20 +252,16 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) if (copy_from_user(, (void __user *)(uintptr_t)argp->data, sizeof(params))) return -EFAULT; - start = kzalloc(sizeof(*start), GFP_KERNEL_ACCOUNT); - if (!start) - return -ENOMEM; + memset(, 0, sizeof(start)); Not needed. dh_blob = NULL; if (params.dh_uaddr) { dh_blob = psp_copy_user_blob(params.dh_uaddr, params.dh_len); - if (IS_ERR(dh_blob)) { - ret = PTR_ERR(dh_blob); - goto e_free; - } + if (IS_ERR(dh_blob)) + return PTR_ERR(dh_blob); - start->dh_cert_address = __sme_set(__pa(dh_blob)); - start->dh_cert_len = params.dh_len; + start.dh_cert_address = __sme_set(__pa(dh_blob)); + start.dh_cert_len = params.dh_len; } session_blob = NULL; @@ -294,40 +272,38 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) goto e_free_dh; } - start->session_address = __sme_set(__pa(session_blob)); - start->session_len = params.session_len; + start.session_address = __sme_set(__pa(session_blob)); + start.session_len = params.session_len; } - start->handle = params.handle; - start->policy = params.policy; + start.handle = params.handle; + start.policy = params.policy; /* create memory encryption context */ - ret =
Re: [PATCH v7 1/8] pwm: pca9685: Switch to atomic API
Hello, On Tue, Apr 06, 2021 at 06:41:33PM +0200, Clemens Gruber wrote: > The switch to the atomic API goes hand in hand with a few fixes to > previously experienced issues: > - The duty cycle is no longer lost after disable/enable (previously the > OFF registers were cleared in disable and the user was required to > call config to restore the duty cycle settings) > - If one sets a period resulting in the same prescale register value, > the sleep and write to the register is now skipped > > Signed-off-by: Clemens Gruber > --- > Changes since v6: > - Order of a comparison switched for improved readability > > Changes since v5: > - Function documentation for set_duty > - Variable initializations > - Print warning if all LEDs channel > - Changed EOPNOTSUPP to EINVAL > - Improved error messages > - Register reset corrections moved to this patch > > Changes since v4: > - Patches split up > - Use a single set_duty function > - Improve readability / new macros > - Added a patch to restrict prescale changes to the first user > > Changes since v3: > - Refactoring: Extracted common functions > - Read prescale register value instead of caching it > - Return all zeros and disabled for "all LEDs" channel state > - Improved duty calculation / mapping to 0..4096 > > Changes since v2: > - Always set default prescale value in probe > - Simplified probe code > - Inlined functions with one callsite > > Changes since v1: > - Fixed a logic error > - Impoved PM runtime handling and fixed !CONFIG_PM > - Write default prescale reg value if invalid in probe > - Reuse full_off/_on functions throughout driver > - Use cached prescale value whenever possible > > drivers/pwm/pwm-pca9685.c | 261 ++ > 1 file changed, 92 insertions(+), 169 deletions(-) > > diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c > index 4a55dc18656c..5a2ce97e71fd 100644 > --- a/drivers/pwm/pwm-pca9685.c > +++ b/drivers/pwm/pwm-pca9685.c > @@ -51,7 +51,6 @@ > #define PCA9685_PRESCALE_MAX 0xFF/* => min. frequency of 24 Hz */ > > #define PCA9685_COUNTER_RANGE4096 > -#define PCA9685_DEFAULT_PERIOD 500 /* Default period_ns = 1/200 Hz > */ > #define PCA9685_OSC_CLOCK_MHZ25 /* Internal oscillator with 25 > MHz */ > > #define PCA9685_NUMREGS 0xFF > @@ -71,10 +70,14 @@ > #define LED_N_OFF_H(N) (PCA9685_LEDX_OFF_H + (4 * (N))) > #define LED_N_OFF_L(N) (PCA9685_LEDX_OFF_L + (4 * (N))) > > +#define REG_ON_H(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_ON_H : > LED_N_ON_H((C))) > +#define REG_ON_L(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_ON_L : > LED_N_ON_L((C))) > +#define REG_OFF_H(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_OFF_H : > LED_N_OFF_H((C))) > +#define REG_OFF_L(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_OFF_L : > LED_N_OFF_L((C))) > + > struct pca9685 { > struct pwm_chip chip; > struct regmap *regmap; > - int period_ns; > #if IS_ENABLED(CONFIG_GPIOLIB) > struct mutex lock; > struct gpio_chip gpio; > @@ -87,6 +90,51 @@ static inline struct pca9685 *to_pca(struct pwm_chip *chip) > return container_of(chip, struct pca9685, chip); > } > > +/* Helper function to set the duty cycle ratio to duty/4096 (e.g. duty=2048 > -> 50%) */ > +static void pca9685_pwm_set_duty(struct pca9685 *pca, int channel, unsigned > int duty) > +{ > + if (duty == 0) { > + /* Set the full OFF bit, which has the highest precedence */ > + regmap_write(pca->regmap, REG_OFF_H(channel), LED_FULL); > + } else if (duty >= PCA9685_COUNTER_RANGE) { > + /* Set the full ON bit and clear the full OFF bit */ > + regmap_write(pca->regmap, REG_ON_H(channel), LED_FULL); > + regmap_write(pca->regmap, REG_OFF_H(channel), 0); > + } else { > + /* Set OFF time (clears the full OFF bit) */ > + regmap_write(pca->regmap, REG_OFF_L(channel), duty & 0xff); > + regmap_write(pca->regmap, REG_OFF_H(channel), (duty >> 8) & > 0xf); > + /* Clear the full ON bit */ > + regmap_write(pca->regmap, REG_ON_H(channel), 0); > + } > +} > + > +static unsigned int pca9685_pwm_get_duty(struct pca9685 *pca, int channel) > +{ > + unsigned int off_h = 0, val = 0; > + > + if (WARN_ON(channel >= PCA9685_MAXCHAN)) { > + /* HW does not support reading state of "all LEDs" channel */ > + return 0; > + } > + > + regmap_read(pca->regmap, LED_N_OFF_H(channel), _h); > + if (off_h & LED_FULL) { > + /* Full OFF bit is set */ > + return 0; > + } > + > + regmap_read(pca->regmap, LED_N_ON_H(channel), ); > + if (val & LED_FULL) { > + /* Full ON bit is set */ > + return PCA9685_COUNTER_RANGE; > + } > + > + val = 0; Why do you set val to 0 first? Do you get a compiler warning otherwise? > +
Re: [RESEND PATCH v5 1/2] bio: limit bio max size
> On Wed, Apr 07, 2021 at 09:16:12AM +0900, Changheun Lee wrote: > > > On Tue, Apr 06, 2021 at 10:31:28AM +0900, Changheun Lee wrote: > > > > > bio size can grow up to 4GB when muli-page bvec is enabled. > > > > > but sometimes it would lead to inefficient behaviors. > > > > > in case of large chunk direct I/O, - 32MB chunk read in user space - > > > > > all pages for 32MB would be merged to a bio structure if the pages > > > > > physical addresses are contiguous. it makes some delay to submit > > > > > until merge complete. bio max size should be limited to a proper size. > > > > > > > > > > When 32MB chunk read with direct I/O option is coming from userspace, > > > > > kernel behavior is below now in do_direct_IO() loop. it's timeline. > > > > > > > > > > | bio merge for 32MB. total 8,192 pages are merged. > > > > > | total elapsed time is over 2ms. > > > > > |-- ... --->| > > > > > | 8,192 pages merged > > > > > a bio. > > > > > | at this time, > > > > > first bio submit is done. > > > > > | 1 bio is split to > > > > > 32 read request and issue. > > > > > |---> > > > > > |---> > > > > >|---> > > > > > .. > > > > > > > > > > |---> > > > > > > > > > > |--->| > > > > > total 19ms elapsed to complete 32MB read > > > > > done from device. | > > > > > > > > > > If bio max size is limited with 1MB, behavior is changed below. > > > > > > > > > > | bio merge for 1MB. 256 pages are merged for each bio. > > > > > | total 32 bio will be made. > > > > > | total elapsed time is over 2ms. it's same. > > > > > | but, first bio submit timing is fast. about 100us. > > > > > |--->|--->|--->|---> ... -->|--->|--->|--->|--->| > > > > > | 256 pages merged a bio. > > > > > | at this time, first bio submit is done. > > > > > | and 1 read request is issued for 1 bio. > > > > > |---> > > > > >|---> > > > > > |---> > > > > > .. > > > > > |---> > > > > > |--->| > > > > > total 17ms elapsed to complete 32MB read done from device. | > > > > > > > > > > As a result, read request issue timing is faster if bio max size is > > > > > limited. > > > > > Current kernel behavior with multipage bvec, super large bio can be > > > > > created. > > > > > And it lead to delay first I/O request issue. > > > > > > > > > > Signed-off-by: Changheun Lee > > > > > --- > > > > > block/bio.c| 13 - > > > > > include/linux/bio.h| 2 +- > > > > > include/linux/blkdev.h | 3 +++ > > > > > 3 files changed, 16 insertions(+), 2 deletions(-) > > > > > > > > > > diff --git a/block/bio.c b/block/bio.c > > > > > index 1f2cc1fbe283..c528e1f944c7 100644 > > > > > --- a/block/bio.c > > > > > +++ b/block/bio.c > > > > > @@ -287,6 +287,17 @@ void bio_init(struct bio *bio, struct bio_vec > > > > > *table, > > > > > } > > > > > EXPORT_SYMBOL(bio_init); > > > > > > > > > > +unsigned int bio_max_size(struct bio *bio) > > > > > +{ > > > > > + struct request_queue *q = bio->bi_disk->queue; > > > > > + > > > > > + if (blk_queue_limit_bio_size(q)) > > > > > + return blk_queue_get_max_sectors(q, bio_op(bio)) > > > > > + << SECTOR_SHIFT; > > > > > + > > > > > + return UINT_MAX; > > > > > +} > > > > > + > > > > > /** > > > > > * bio_reset - reinitialize a bio > > > > > * @bio: bio to reset > > > > > @@ -877,7 +888,7 @@ bool __bio_try_merge_page(struct bio *bio, struct > > > > > page *page, > > > > > struct bio_vec *bv = >bi_io_vec[bio->bi_vcnt - 1]; > > > > > > > > > > if (page_is_mergeable(bv, page, len, off, same_page)) { > > > > > - if (bio->bi_iter.bi_size > UINT_MAX - len) { > > > > > + if (bio->bi_iter.bi_size > bio_max_size(bio) - > > > > > len) { > > > > > *same_page = false; > > > > > return false; > > > > > } > > > > > diff --git a/include/linux/bio.h b/include/linux/bio.h > > > > > index 1edda614f7ce..13b6f6562a5b 100644 > > > > > --- a/include/linux/bio.h > > > > > +++ b/include/linux/bio.h > > > > > @@ -113,7 +113,7 @@ static inline bool
Re: [PATCH -next] tty: n_gsm: use DEFINE_SPINLOCK() for spinlock
On 06. 04. 21, 13:56, Huang Guobin wrote: From: Guobin Huang spinlock can be initialized automatically with DEFINE_SPINLOCK() rather than explicitly calling spin_lock_init(). Reported-by: Hulk Robot Signed-off-by: Guobin Huang Reviewed-by: Jiri Slaby --- drivers/tty/n_gsm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 9e12f9cb1a98..d60cffc70a0c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -266,7 +266,7 @@ struct gsm_mux { #define MAX_MUX 4 /* 256 minors */ static struct gsm_mux *gsm_mux[MAX_MUX]; /* GSM muxes */ -static spinlock_t gsm_mux_lock; +static DEFINE_SPINLOCK(gsm_mux_lock); static struct tty_driver *gsm_tty_driver; @@ -3257,8 +3257,6 @@ static int __init gsm_init(void) gsm_tty_driver->init_termios.c_lflag &= ~ECHO; tty_set_operations(gsm_tty_driver, _ops); - spin_lock_init(_mux_lock); - if (tty_register_driver(gsm_tty_driver)) { put_tty_driver(gsm_tty_driver); tty_unregister_ldisc(N_GSM0710); -- js
[PATCH] usb: cdns3: Fix rumtime PM imbalance on error
When cdns3_gadget_start() fails, a pairing PM usage counter decrement is needed to keep the counter balanced. Signed-off-by: Dinghao Liu --- drivers/usb/cdns3/cdns3-gadget.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 582bfeceedb4..ad891a108aed 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -3255,8 +3255,11 @@ static int __cdns3_gadget_init(struct cdns *cdns) pm_runtime_get_sync(cdns->dev); ret = cdns3_gadget_start(cdns); - if (ret) + if (ret) { + pm_runtime_mark_last_busy(cdns->dev); + pm_runtime_put_autosuspend(cdns->dev); return ret; + } /* * Because interrupt line can be shared with other components in -- 2.17.1
Re: [PATCH v2 7/8] crypto: ccp: Use the stack and common buffer for INIT command
Le 07/04/2021 à 00:49, Sean Christopherson a écrit : Drop the dedicated init_cmd_buf and instead use a local variable. Now that the low level helper uses an internal buffer for all commands, using the stack for the upper layers is safe even when running with CONFIG_VMAP_STACK=y. Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 10 ++ drivers/crypto/ccp/sev-dev.h | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index e54774b0d637..9ff28df03030 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -233,6 +233,7 @@ static int sev_do_cmd(int cmd, void *data, int *psp_ret) static int __sev_platform_init_locked(int *error) { struct psp_device *psp = psp_master; + struct sev_data_init data; struct sev_data_init data = {0, 0, 0, 0}; struct sev_device *sev; int rc = 0; @@ -244,6 +245,7 @@ static int __sev_platform_init_locked(int *error) if (sev->state == SEV_STATE_INIT) return 0; + memset(, 0, sizeof(data)); Not needed. if (sev_es_tmr) { u64 tmr_pa; @@ -253,12 +255,12 @@ static int __sev_platform_init_locked(int *error) */ tmr_pa = __pa(sev_es_tmr); - sev->init_cmd_buf.flags |= SEV_INIT_FLAGS_SEV_ES; - sev->init_cmd_buf.tmr_address = tmr_pa; - sev->init_cmd_buf.tmr_len = SEV_ES_TMR_SIZE; + data.flags |= SEV_INIT_FLAGS_SEV_ES; + data.tmr_address = tmr_pa; + data.tmr_len = SEV_ES_TMR_SIZE; } - rc = __sev_do_cmd_locked(SEV_CMD_INIT, >init_cmd_buf, error); + rc = __sev_do_cmd_locked(SEV_CMD_INIT, , error); if (rc) return rc; diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index 0fd21433f627..666c21eb81ab 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -46,7 +46,6 @@ struct sev_device { unsigned int int_rcvd; wait_queue_head_t int_queue; struct sev_misc_dev *misc; - struct sev_data_init init_cmd_buf; u8 api_major; u8 api_minor;
Re: [PATCH v2 5/8] crypto: ccp: Use the stack for small SEV command buffers
Le 07/04/2021 à 00:49, Sean Christopherson a écrit : For commands with small input/output buffers, use the local stack to "allocate" the structures used to communicate with the PSP. Now that __sev_do_cmd_locked() gracefully handles vmalloc'd buffers, there's no reason to avoid using the stack, e.g. CONFIG_VMAP_STACK=y will just work. Signed-off-by: Sean Christopherson --- drivers/crypto/ccp/sev-dev.c | 122 ++- 1 file changed, 47 insertions(+), 75 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 4aedbdaffe90..bb0d6de071e6 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -396,7 +396,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) { struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pek_csr input; - struct sev_data_pek_csr *data; + struct sev_data_pek_csr data; struct sev_data_pek_csr data = {0, 0}; void __user *input_address; void *blob = NULL; int ret; @@ -407,29 +407,24 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - /* userspace wants to query CSR length */ - if (!input.address || !input.length) + if (!input.address || !input.length) { + data.address = 0; + data.len = 0; With the change proposed above, those two new lines are unneeded. goto cmd; + } /* allocate a physically contiguous buffer to store the CSR blob */ input_address = (void __user *)input.address; - if (input.length > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.length > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; blob = kmalloc(input.length, GFP_KERNEL); - if (!blob) { - ret = -ENOMEM; - goto e_free; - } + if (!blob) + return -ENOMEM; - data->address = __psp_pa(blob); - data->len = input.length; + data.address = __psp_pa(blob); + data.len = input.length; cmd: if (sev->state == SEV_STATE_UNINIT) { @@ -438,10 +433,10 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) goto e_free_blob; } - ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, >error); + ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, , >error); /* If we query the CSR length, FW responded with expected data. */ - input.length = data->len; + input.length = data.len; if (copy_to_user((void __user *)argp->data, , sizeof(input))) { ret = -EFAULT; @@ -455,8 +450,6 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) e_free_blob: kfree(blob); -e_free: - kfree(data); return ret; } @@ -588,7 +581,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) { struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pek_cert_import input; - struct sev_data_pek_cert_import *data; + struct sev_data_pek_cert_import data; void *pek_blob, *oca_blob; int ret; @@ -598,19 +591,14 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - /* copy PEK certificate blobs from userspace */ pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len); - if (IS_ERR(pek_blob)) { - ret = PTR_ERR(pek_blob); - goto e_free; - } + if (IS_ERR(pek_blob)) + return PTR_ERR(pek_blob); - data->pek_cert_address = __psp_pa(pek_blob); - data->pek_cert_len = input.pek_cert_len; + data.reserved = 0; + data.pek_cert_address = __psp_pa(pek_blob); + data.pek_cert_len = input.pek_cert_len; /* copy PEK certificate blobs from userspace */ oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len); @@ -619,8 +607,8 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) goto e_free_pek; } - data->oca_cert_address = __psp_pa(oca_blob); - data->oca_cert_len = input.oca_cert_len; + data.oca_cert_address = __psp_pa(oca_blob); + data.oca_cert_len = input.oca_cert_len; /* If platform is not in INIT state then transition it to INIT */ if (sev->state != SEV_STATE_INIT) { @@ -629,21 +617,19 @@ static int
Re: [PATCH v3 2/2] iio: temperature: add driver support for ti tmp117
On Wed, Apr 7, 2021 at 10:26 AM Lars-Peter Clausen wrote: > > On 4/6/21 8:28 PM, Puranjay Mohan wrote: > > + > > +static int tmp117_write_raw(struct iio_dev *indio_dev, > > + struct iio_chan_spec const *channel, int val, > > + int val2, long mask) > > +{ > > + struct tmp117_data *data = iio_priv(indio_dev); > > + s16 off; > > + > > + switch (mask) { > > + case IIO_CHAN_INFO_CALIBBIAS: > > + off = clamp(val, -32768, 32767); > > + if (off == data->calibbias) > > data->calibbias is only set in probe() and always 0. I'm not sure we > need to cache the value. Reading it back from the device seems fine. I forgot to update it, thanks for finding the bug. Actually, I wanted to update the calibbias register only if a different value is being written. If the same value is written to the device repeatedly then we can save some I2C writes using this. and while reading the calibbias, it is read from the device only. I will fix the bug in the next revision. > > > + return 0; > > + return i2c_smbus_write_word_swapped(data->client, > > + TMP117_REG_TEMP_OFFSET, off); > > + > > + default: > > + return -EINVAL; > > + } > > +} > > + > -- Thanks and Regards Yours Truly, Puranjay Mohan
Re: [PATCH] bus: mhi: pci_generic: Add SDX65 based modem support
On Fri, Apr 02, 2021 at 02:33:19PM -0700, Bhaumik Bhatt wrote: > Add generic info for SDX65 based modems. > > Signed-off-by: Bhaumik Bhatt Reviewed-by: Manivannan Sadhasivam Thanks, Mani > --- > This patch was tested on SDX65 hardware with Ubuntu X86_64 PC as host. > > drivers/bus/mhi/pci_generic.c | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c > index 5cf44bc..92a1b18 100644 > --- a/drivers/bus/mhi/pci_generic.c > +++ b/drivers/bus/mhi/pci_generic.c > @@ -204,6 +204,15 @@ static struct mhi_controller_config > modem_qcom_v1_mhiv_config = { > .event_cfg = modem_qcom_v1_mhi_events, > }; > > +static const struct mhi_pci_dev_info mhi_qcom_sdx65_info = { > + .name = "qcom-sdx65m", > + .fw = "qcom/sdx65m/xbl.elf", > + .edl = "qcom/sdx65m/edl.mbn", > + .config = _qcom_v1_mhiv_config, > + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, > + .dma_data_width = 32 > +}; > + > static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { > .name = "qcom-sdx55m", > .fw = "qcom/sdx55m/sbl1.mbn", > @@ -261,6 +270,8 @@ static const struct mhi_pci_dev_info > mhi_quectel_em1xx_info = { > }; > > static const struct pci_device_id mhi_pci_id_table[] = { > + { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), > + .driver_data = (kernel_ulong_t) _qcom_sdx65_info }, This should come last. I'll fix it while applying. Thanks, Mani > { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0306), > .driver_data = (kernel_ulong_t) _qcom_sdx55_info }, > { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project >
[PATCH] mfd: arizona: Fix rumtime PM imbalance on error
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error. Signed-off-by: Dinghao Liu --- drivers/mfd/arizona-irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 077d9ab112b7..d919ae9691e2 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -100,7 +100,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) unsigned int val; int ret; - ret = pm_runtime_get_sync(arizona->dev); + ret = pm_runtime_resume_and_get(arizona->dev); if (ret < 0) { dev_err(arizona->dev, "Failed to resume device: %d\n", ret); return IRQ_NONE; -- 2.17.1
Re: [RESEND PATCH] bus: mhi: core: Remove pre_init flag used for power purposes
On Thu, Apr 01, 2021 at 02:41:49PM -0700, Bhaumik Bhatt wrote: > Some controllers can choose to skip preparation for power up. > In that case, device context is initialized based on the pre_init > flag not being set during mhi_prepare_for_power_up(). There is no > reason MHI host driver should maintain and provide controllers > with two separate paths for preparing MHI. > > Going forward, all controllers will be required to call the > mhi_prepare_for_power_up() API followed by their choice of sync > or async power up. This allows MHI host driver to get rid of the > pre_init flag and sets up a common way for all controllers to use > MHI. This also helps controllers fail early on during preparation > phase in some failure cases. > > Signed-off-by: Bhaumik Bhatt I hope Jeff is also okay with this patch for AIC100. Reviewed-by: Manivannan Sadhasivam Thanks, Mani > --- > This patch was tested on arm64 architecture. > > drivers/bus/mhi/core/init.c | 3 --- > drivers/bus/mhi/core/pm.c | 20 > include/linux/mhi.h | 2 -- > 3 files changed, 25 deletions(-) > > diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c > index d1d9b0d..1f61352 100644 > --- a/drivers/bus/mhi/core/init.c > +++ b/drivers/bus/mhi/core/init.c > @@ -1080,8 +1080,6 @@ int mhi_prepare_for_power_up(struct mhi_controller > *mhi_cntrl) > mhi_rddm_prepare(mhi_cntrl, mhi_cntrl->rddm_image); > } > > - mhi_cntrl->pre_init = true; > - > mutex_unlock(_cntrl->pm_mutex); > > return 0; > @@ -1112,7 +1110,6 @@ void mhi_unprepare_after_power_down(struct > mhi_controller *mhi_cntrl) > } > > mhi_deinit_dev_ctxt(mhi_cntrl); > - mhi_cntrl->pre_init = false; > } > EXPORT_SYMBOL_GPL(mhi_unprepare_after_power_down); > > diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c > index e4aff77..b23eec5 100644 > --- a/drivers/bus/mhi/core/pm.c > +++ b/drivers/bus/mhi/core/pm.c > @@ -1062,13 +1062,6 @@ int mhi_async_power_up(struct mhi_controller > *mhi_cntrl) > mutex_lock(_cntrl->pm_mutex); > mhi_cntrl->pm_state = MHI_PM_DISABLE; > > - if (!mhi_cntrl->pre_init) { > - /* Setup device context */ > - ret = mhi_init_dev_ctxt(mhi_cntrl); > - if (ret) > - goto error_dev_ctxt; > - } > - > ret = mhi_init_irq_setup(mhi_cntrl); > if (ret) > goto error_setup_irq; > @@ -1150,10 +1143,6 @@ int mhi_async_power_up(struct mhi_controller > *mhi_cntrl) > mhi_deinit_free_irq(mhi_cntrl); > > error_setup_irq: > - if (!mhi_cntrl->pre_init) > - mhi_deinit_dev_ctxt(mhi_cntrl); > - > -error_dev_ctxt: > mhi_cntrl->pm_state = MHI_PM_DISABLE; > mutex_unlock(_cntrl->pm_mutex); > > @@ -1203,15 +1192,6 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, > bool graceful) > flush_work(_cntrl->st_worker); > > free_irq(mhi_cntrl->irq[0], mhi_cntrl); > - > - if (!mhi_cntrl->pre_init) { > - /* Free all allocated resources */ > - if (mhi_cntrl->fbc_image) { > - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); > - mhi_cntrl->fbc_image = NULL; > - } > - mhi_deinit_dev_ctxt(mhi_cntrl); > - } > } > EXPORT_SYMBOL_GPL(mhi_power_down); > > diff --git a/include/linux/mhi.h b/include/linux/mhi.h > index b16afd3..c9b36a3 100644 > --- a/include/linux/mhi.h > +++ b/include/linux/mhi.h > @@ -354,7 +354,6 @@ struct mhi_controller_config { > * @index: Index of the MHI controller instance > * @bounce_buf: Use of bounce buffer > * @fbc_download: MHI host needs to do complete image transfer (optional) > - * @pre_init: MHI host needs to do pre-initialization before power up > * @wake_set: Device wakeup set flag > * @irq_flags: irq flags passed to request_irq (optional) > * > @@ -447,7 +446,6 @@ struct mhi_controller { > int index; > bool bounce_buf; > bool fbc_download; > - bool pre_init; > bool wake_set; > unsigned long irq_flags; > }; > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project >
Re: [RESEND PATCH v5 1/2] bio: limit bio max size
On Wed, Apr 07, 2021 at 09:16:12AM +0900, Changheun Lee wrote: > > On Tue, Apr 06, 2021 at 10:31:28AM +0900, Changheun Lee wrote: > > > > bio size can grow up to 4GB when muli-page bvec is enabled. > > > > but sometimes it would lead to inefficient behaviors. > > > > in case of large chunk direct I/O, - 32MB chunk read in user space - > > > > all pages for 32MB would be merged to a bio structure if the pages > > > > physical addresses are contiguous. it makes some delay to submit > > > > until merge complete. bio max size should be limited to a proper size. > > > > > > > > When 32MB chunk read with direct I/O option is coming from userspace, > > > > kernel behavior is below now in do_direct_IO() loop. it's timeline. > > > > > > > > | bio merge for 32MB. total 8,192 pages are merged. > > > > | total elapsed time is over 2ms. > > > > |-- ... --->| > > > > | 8,192 pages merged a > > > > bio. > > > > | at this time, first > > > > bio submit is done. > > > > | 1 bio is split to 32 > > > > read request and issue. > > > > |---> > > > > |---> > > > >|---> > > > > .. > > > > > > > > |---> > > > > > > > > |--->| > > > > total 19ms elapsed to complete 32MB read done > > > > from device. | > > > > > > > > If bio max size is limited with 1MB, behavior is changed below. > > > > > > > > | bio merge for 1MB. 256 pages are merged for each bio. > > > > | total 32 bio will be made. > > > > | total elapsed time is over 2ms. it's same. > > > > | but, first bio submit timing is fast. about 100us. > > > > |--->|--->|--->|---> ... -->|--->|--->|--->|--->| > > > > | 256 pages merged a bio. > > > > | at this time, first bio submit is done. > > > > | and 1 read request is issued for 1 bio. > > > > |---> > > > >|---> > > > > |---> > > > > .. > > > > |---> > > > > |--->| > > > > total 17ms elapsed to complete 32MB read done from device. | > > > > > > > > As a result, read request issue timing is faster if bio max size is > > > > limited. > > > > Current kernel behavior with multipage bvec, super large bio can be > > > > created. > > > > And it lead to delay first I/O request issue. > > > > > > > > Signed-off-by: Changheun Lee > > > > --- > > > > block/bio.c| 13 - > > > > include/linux/bio.h| 2 +- > > > > include/linux/blkdev.h | 3 +++ > > > > 3 files changed, 16 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/block/bio.c b/block/bio.c > > > > index 1f2cc1fbe283..c528e1f944c7 100644 > > > > --- a/block/bio.c > > > > +++ b/block/bio.c > > > > @@ -287,6 +287,17 @@ void bio_init(struct bio *bio, struct bio_vec > > > > *table, > > > > } > > > > EXPORT_SYMBOL(bio_init); > > > > > > > > +unsigned int bio_max_size(struct bio *bio) > > > > +{ > > > > + struct request_queue *q = bio->bi_disk->queue; > > > > + > > > > + if (blk_queue_limit_bio_size(q)) > > > > + return blk_queue_get_max_sectors(q, bio_op(bio)) > > > > + << SECTOR_SHIFT; > > > > + > > > > + return UINT_MAX; > > > > +} > > > > + > > > > /** > > > > * bio_reset - reinitialize a bio > > > > * @bio: bio to reset > > > > @@ -877,7 +888,7 @@ bool __bio_try_merge_page(struct bio *bio, struct > > > > page *page, > > > > struct bio_vec *bv = >bi_io_vec[bio->bi_vcnt - 1]; > > > > > > > > if (page_is_mergeable(bv, page, len, off, same_page)) { > > > > - if (bio->bi_iter.bi_size > UINT_MAX - len) { > > > > + if (bio->bi_iter.bi_size > bio_max_size(bio) - > > > > len) { > > > > *same_page = false; > > > > return false; > > > > } > > > > diff --git a/include/linux/bio.h b/include/linux/bio.h > > > > index 1edda614f7ce..13b6f6562a5b 100644 > > > > --- a/include/linux/bio.h > > > > +++ b/include/linux/bio.h > > > > @@ -113,7 +113,7 @@ static inline bool bio_full(struct bio *bio, > > > > unsigned len) > > > > if (bio->bi_vcnt >= bio->bi_max_vecs) > > > > return true; > > > > > > > > - if
Re: High kmalloc-32 slab cache consumption with 10k containers
On Wed, Apr 07, 2021 at 08:28:07AM +1000, Dave Chinner wrote: > On Mon, Apr 05, 2021 at 11:18:48AM +0530, Bharata B Rao wrote: > > Hi, > > > > When running 1 (more-or-less-empty-)containers on a bare-metal Power9 > > server(160 CPUs, 2 NUMA nodes, 256G memory), it is seen that memory > > consumption increases quite a lot (around 172G) when the containers are > > running. Most of it comes from slab (149G) and within slab, the majority of > > it comes from kmalloc-32 cache (102G) > > > > The major allocator of kmalloc-32 slab cache happens to be the list_head > > allocations of list_lru_one list. These lists are created whenever a > > FS mount happens. Specially two such lists are registered by alloc_super(), > > one for dentry and another for inode shrinker list. And these lists > > are created for all possible NUMA nodes and for all given memcgs > > (memcg_nr_cache_ids to be particular) > > > > If, > > > > A = Nr allocation request per mount: 2 (one for dentry and inode list) > > B = Nr NUMA possible nodes > > C = memcg_nr_cache_ids > > D = size of each kmalloc-32 object: 32 bytes, > > > > then for every mount, the amount of memory consumed by kmalloc-32 slab > > cache for list_lru creation is A*B*C*D bytes. > > > > Following factors contribute to the excessive allocations: > > > > - Lists are created for possible NUMA nodes. > > - memcg_nr_cache_ids grows in bulk (see memcg_alloc_cache_id() and > > additional > > list_lrus are created when it grows. Thus we end up creating list_lru_one > > list_heads even for those memcgs which are yet to be created. > > For example, when 1 memcgs are created, memcg_nr_cache_ids reach > > a value of 12286. > > So, by your numbers, we have 2 * 2 * 12286 * 32 = 1.5MB per mount. > > So for that to make up 100GB of RAM, you must have somewhere over > 500,000 mounted superblocks on the machine? > > That implies 50+ unique mounted superblocks per container, which > seems like an awful lot. Here is how the calculation turns out to be in my setup: Number of possible NUMA nodes = 2 Number of mounts per container = 7 (Check below to see which are these) Number of list creation requests per mount = 2 Number of containers = 1 memcg_nr_cache_ids for 10k containers = 12286 size of kmalloc-32 = 32 byes 2*7*2*1*12286*32 = 11008256 bytes = 102.5G > > > - When a memcg goes offline, the list elements are drained to the parent > > memcg, but the list_head entry remains. > > - The lists are destroyed only when the FS is unmounted. So list_heads > > for non-existing memcgs remain and continue to contribute to the > > kmalloc-32 allocation. This is presumably done for performance > > reason as they get reused when new memcgs are created, but they end up > > consuming slab memory until then. > > - In case of containers, a few file systems get mounted and are specific > > to the container namespace and hence to a particular memcg, but we > > end up creating lists for all the memcgs. > > As an example, if 7 FS mounts are done for every container and when > > 10k containers are created, we end up creating 2*7*12286 list_lru_one > > lists for each NUMA node. It appears that no elements will get added > > to other than 2*7=14 of them in the case of containers. > > Yeah, at first glance this doesn't strike me as a problem with the > list_lru structure, it smells more like a problem resulting from a > huge number of superblock instantiations on the machine. Which, > probably, mostly have no significant need for anything other than a > single memcg awareness? > > Can you post a typical /proc/self/mounts output from one of these > idle/empty containers so we can see exactly how many mounts and > their type are being instantiated in each container? Tracing type->name in alloc_super() lists these 7 types for every container. 3-2691[041] 222.761041: alloc_super: fstype: mqueue 3-2692[072] 222.812187: alloc_super: fstype: proc 3-2692[072] 222.812261: alloc_super: fstype: tmpfs 3-2692[072] 222.812329: alloc_super: fstype: devpts 3-2692[072] 222.812392: alloc_super: fstype: tmpfs 3-2692[072] 222.813102: alloc_super: fstype: tmpfs 3-2692[072] 222.813159: alloc_super: fstype: tmpfs > > > One straight forward way to prevent this excessive list_lru_one > > allocations is to limit the list_lru_one creation only to the > > relevant memcg. However I don't see an easy way to figure out > > that relevant memcg from FS mount path (alloc_super()) > > Superblocks have to support an unknown number of memcgs after they > have been mounted. bind mounts, child memcgs, etc, all mean that we > can't just have a static, single mount time memcg instantiation. > > > As an alternative approach, I have this below hack that does lazy > > list_lru creation. The memcg-specific list is created and initialized > > only when there is a request to add an element to that particular > > list.
Re: [PATCH] fs/debugfs: Convert to DEFINE_SHOW_ATTRIBUTE
On Wed, Apr 07, 2021 at 10:22:06AM +0800, Zuo Qi Lin wrote: > On Fri, 2 Apr 2021 14:22:24 +0200 > Greg KH wrote: > > > On Fri, Apr 02, 2021 at 08:11:41PM +0800, zuoqil...@163.com wrote: > > > From: zuoqilin > > > > Please use your full/real name. > > > > thanks, > > > > greg k-h > > --- > Hi > > My name is Zuo Qilin. Great! Then use that above :) Also that name does not match your "From: " name in your email, here either, so please just get them all the same when sending a patch. thanks, greg k-h
Re: [PATCH v4 3/7] regulator: IRQ based event/error notification helpers
Morning Andy, Thanks for the review! By the way, is it me or did your mail-client spill this out using HTML? On Wed, 2021-04-07 at 01:44 +0300, Andy Shevchenko wrote: > On Tuesday, April 6, 2021, Matti Vaittinen < > matti.vaitti...@fi.rohmeurope.com> wrote: > > +static void die_loudly(const char *msg) > > +{ > > + pr_emerg(msg); > > Oh là là, besides build bot complaints, this has serious security > implications. Never do like this. I'm not even trying to claim that was correct. And I did send a fixup - sorry for this. I don't intend to do this again. Now, when this is said - If you have a minute, please educate me. Assuming we know all the callers and that all the callers use this as die_loudly("foobarfoo\n"); - what is the exploit mechanism? > > + BUG(); > > +} > > + > > +/** > > + * regulator_irq_helper - register IRQ based regulator event/error > > notifier > > + * > > + * @dev: device to which lifetime the helper's > > lifetime is > > + * bound. > > + * @d: IRQ helper descriptor. > > + * @irq: IRQ used to inform events/errors to be > > notified. > > + * @irq_flags: Extra IRQ flags to be OR's with the default > > IRQF_ONESHOT > > + * when requesting the (threaded) irq. > > + * @common_errs: Errors which can be flagged by this IRQ for > > all rdevs. > > + * When IRQ is re-enabled these errors will be > > cleared > > + * from all associated regulators > > + * @per_rdev_errs: Optional error flag array describing errors > > specific > > + * for only some of the regulators. These > > errors will be > > + * or'ed with common erros. If this is given > > the array > > + * should contain rdev_amount flags. Can be > > set to NULL > > + * if there is no regulator specific error > > flags for this > > + * IRQ. > > + * @rdev: Array of regulators associated with this > > IRQ. > > + * @rdev_amount: Amount of regulators associated wit this > > IRQ. > > + */ > > +void *regulator_irq_helper(struct device *dev, > > + const struct regulator_irq_desc *d, int > > irq, > > + int irq_flags, int common_errs, int > > *per_rdev_errs, > > + struct regulator_dev **rdev, int > > rdev_amount) > > +{ > > + struct regulator_irq *h; > > + int ret; > > + > > + if (!rdev_amount || !d || !d->map_event || !d->name) > > + return ERR_PTR(-EINVAL); > > + > > + if (irq <= 0) { > > + dev_err(dev, "No IRQ\n"); > > + return ERR_PTR(-EINVAL); > > Why shadowing error code? Negative IRQ is anything but “no IRQ”. This was a good point. The irq is passed here as parameter. From this function's perspective the negative irq is invalid parameter - we don't know how the caller has obtained it. Print could show the value contained in irq though. Now that you pointed this out I am unsure if this check is needed here. If we check it, then I still think we should report -EINVAL for invalid parameter. Other option is to just call the request_threaded_irq() - log the IRQ request failure and return what request_threaded_irq() returns. Do you think that would make sense? > > + > > +/** > > + * regulator_irq_helper_cancel - drop IRQ based regulator > > event/error notifier > > + * > > + * @handle:Pointer to handle returned by a successful > > call to > > + * regulator_irq_helper(). Will be NULLed upon > > return. > > + * > > + * The associated IRQ is released and work is cancelled when the > > function > > + * returns. > > + */ > > +void regulator_irq_helper_cancel(void **handle) > > +{ > > + if (handle && *handle) { > > Can handle ever be NULL here ? (Yes, I understand that you export > this) To tell the truth - I am not sure. I *guess* that if we allow this to be NULL, then one *could* implement a driver for IC where IRQs are optional, in a way that when IRQs are supported the pointer to handle is valid, when IRQs aren't supported the pointer is NULL. (Why) do you think we should skip the check? > > > + struct regulator_irq *h = *handle; > > + > > + free_irq(h->irq, h); > > + if (h->desc.irq_off_ms) > > + cancel_delayed_work_sync(>isr_work); > > + > > + h = NULL; > > + } > > +} > > +EXPORT_SYMBOL_GPL(regulator_irq_helper_cancel); > > + > > +static void regulator_irq_helper_drop(struct device *dev, void > > *res) > > +{ > > + regulator_irq_helper_cancel(res); > > +} > > + > > +void *devm_regulator_irq_helper(struct device *dev, > > +const struct regulator_irq_desc > > *d, int irq, > > +int irq_flags, int common_errs, > > +
[PATCH] iio: proximity: pulsedlight: Fix rumtime PM imbalance on error
When lidar_write_control() fails, a pairing PM usage counter decrement is needed to keep the counter balanced. Signed-off-by: Dinghao Liu --- drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index c685f10b5ae4..cc206bfa09c7 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -160,6 +160,7 @@ static int lidar_get_measurement(struct lidar_data *data, u16 *reg) ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE); if (ret < 0) { dev_err(>dev, "cannot send start measurement command"); + pm_runtime_put_noidle(>dev); return ret; } -- 2.17.1
Re: [PATCH v3 2/2] iio: temperature: add driver support for ti tmp117
On 4/6/21 8:28 PM, Puranjay Mohan wrote: + +static int tmp117_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int val, + int val2, long mask) +{ + struct tmp117_data *data = iio_priv(indio_dev); + s16 off; + + switch (mask) { + case IIO_CHAN_INFO_CALIBBIAS: + off = clamp(val, -32768, 32767); + if (off == data->calibbias) data->calibbias is only set in probe() and always 0. I'm not sure we need to cache the value. Reading it back from the device seems fine. + return 0; + return i2c_smbus_write_word_swapped(data->client, + TMP117_REG_TEMP_OFFSET, off); + + default: + return -EINVAL; + } +} +
[RFC v2 net-next 4/4] staging: mt7621-dts: enable MT7530 interrupt controller
Enable MT7530 interrupt controller in the MT7621 SoC. Signed-off-by: DENG Qingfang --- RFC v1 -> RFC v2: - No changes. drivers/staging/mt7621-dts/mt7621.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi index 16fc94f65486..ebf8b0633e88 100644 --- a/drivers/staging/mt7621-dts/mt7621.dtsi +++ b/drivers/staging/mt7621-dts/mt7621.dtsi @@ -447,6 +447,9 @@ switch0: switch0@0 { mediatek,mcm; resets = < 2>; reset-names = "mcm"; + interrupt-controller; + interrupt-parent = <>; + interrupts = ; ports { #address-cells = <1>; -- 2.25.1
[RFC v2 net-next 2/4] net: dsa: mt7530: add interrupt support
Add support for MT7530 interrupt controller to handle internal PHYs. In order to assign an IRQ number to each PHY, the registration of MDIO bus is also done in this driver. Signed-off-by: DENG Qingfang --- RFC v1 -> RFC v2: - Split MDIO and IRQ setup function drivers/net/dsa/Kconfig | 1 + drivers/net/dsa/mt7530.c | 238 +++ drivers/net/dsa/mt7530.h | 18 ++- 3 files changed, 236 insertions(+), 21 deletions(-) diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index a5f1aa911fe2..264384449f09 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -36,6 +36,7 @@ config NET_DSA_LANTIQ_GSWIP config NET_DSA_MT7530 tristate "MediaTek MT753x and MT7621 Ethernet switch support" select NET_DSA_TAG_MTK + select MEDIATEK_PHY help This enables support for the MediaTek MT7530, MT7531, and MT7621 Ethernet switch chips. diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 2bd1bab71497..813703339db0 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -596,18 +597,14 @@ mt7530_mib_reset(struct dsa_switch *ds) mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE); } -static int mt7530_phy_read(struct dsa_switch *ds, int port, int regnum) +static int mt7530_phy_read(struct mt7530_priv *priv, int port, int regnum) { - struct mt7530_priv *priv = ds->priv; - return mdiobus_read_nested(priv->bus, port, regnum); } -static int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum, +static int mt7530_phy_write(struct mt7530_priv *priv, int port, int regnum, u16 val) { - struct mt7530_priv *priv = ds->priv; - return mdiobus_write_nested(priv->bus, port, regnum, val); } @@ -785,9 +782,8 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, } static int -mt7531_ind_phy_read(struct dsa_switch *ds, int port, int regnum) +mt7531_ind_phy_read(struct mt7530_priv *priv, int port, int regnum) { - struct mt7530_priv *priv = ds->priv; int devad; int ret; @@ -803,10 +799,9 @@ mt7531_ind_phy_read(struct dsa_switch *ds, int port, int regnum) } static int -mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum, +mt7531_ind_phy_write(struct mt7530_priv *priv, int port, int regnum, u16 data) { - struct mt7530_priv *priv = ds->priv; int devad; int ret; @@ -1828,6 +1823,202 @@ mt7530_setup_gpio(struct mt7530_priv *priv) } #endif /* CONFIG_GPIOLIB */ +static irqreturn_t +mt7530_irq(int irq, void *data) +{ + struct mt7530_priv *priv = data; + bool handled = false; + u32 val; + int p; + + mutex_lock_nested(>bus->mdio_lock, MDIO_MUTEX_NESTED); + val = mt7530_mii_read(priv, MT7530_SYS_INT_STS); + mt7530_mii_write(priv, MT7530_SYS_INT_STS, val); + mutex_unlock(>bus->mdio_lock); + + for (p = 0; p < MT7530_NUM_PHYS; p++) { + if (BIT(p) & val) { + handle_nested_irq(irq_find_mapping(priv->irq_domain, + p)); + handled = true; + } + } + + return IRQ_RETVAL(handled); +} + +static void +mt7530_irq_mask(struct irq_data *d) +{ + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); + + priv->irq_enable &= ~BIT(d->hwirq); +} + +static void +mt7530_irq_unmask(struct irq_data *d) +{ + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); + + priv->irq_enable |= BIT(d->hwirq); +} + +static void +mt7530_irq_bus_lock(struct irq_data *d) +{ + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); + + mutex_lock_nested(>bus->mdio_lock, MDIO_MUTEX_NESTED); +} + +static void +mt7530_irq_bus_sync_unlock(struct irq_data *d) +{ + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); + + mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); + mutex_unlock(>bus->mdio_lock); +} + +static struct irq_chip mt7530_irq_chip = { + .name = KBUILD_MODNAME, + .irq_mask = mt7530_irq_mask, + .irq_unmask = mt7530_irq_unmask, + .irq_bus_lock = mt7530_irq_bus_lock, + .irq_bus_sync_unlock = mt7530_irq_bus_sync_unlock, +}; + +static int +mt7530_irq_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_chip_data(irq, domain->host_data); + irq_set_chip_and_handler(irq, _irq_chip, handle_simple_irq); + irq_set_noprobe(irq); + + return 0; +} + +static const struct irq_domain_ops mt7530_irq_domain_ops = { + .map = mt7530_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static void +mt7530_setup_mdio_irq(struct mt7530_priv *priv) +{ + struct dsa_switch *ds = priv->ds; + int p; + +
[RFC v2 net-next 3/4] dt-bindings: net: dsa: add MT7530 interrupt controller binding
Add device tree binding to support MT7530 interrupt controller. Signed-off-by: DENG Qingfang --- RFC v1 -> RFC v2: - No changes. Documentation/devicetree/bindings/net/dsa/mt7530.txt | 5 + 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt b/Documentation/devicetree/bindings/net/dsa/mt7530.txt index de04626a8e9d..26b34888eb62 100644 --- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt +++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt @@ -81,6 +81,11 @@ Optional properties: - gpio-controller: Boolean; if defined, MT7530's LED controller will run on GPIO mode. - #gpio-cells: Must be 2 if gpio-controller is defined. +- interrupt-controller: Boolean; Enables the internal interrupt controller. + +If interrupt-controller is defined, the following property is required. + +- interrupts: Parent interrupt for the interrupt controller. See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional required, optional properties and how the integrated switch subnodes must -- 2.25.1
[RFC v2 net-next 0/4] MT7530 interrupt support
Add support for MT7530 interrupt controller. DENG Qingfang (4): net: phy: add MediaTek PHY driver net: dsa: mt7530: add interrupt support dt-bindings: net: dsa: add MT7530 interrupt controller binding staging: mt7621-dts: enable MT7530 interrupt controller .../devicetree/bindings/net/dsa/mt7530.txt| 5 + drivers/net/dsa/mt7530.c | 203 -- drivers/net/dsa/mt7530.h | 18 +- drivers/net/phy/Kconfig | 5 + drivers/net/phy/Makefile | 1 + drivers/net/phy/mediatek.c| 109 ++ drivers/staging/mt7621-dts/mt7621.dtsi| 3 + 7 files changed, 323 insertions(+), 21 deletions(-) create mode 100644 drivers/net/phy/mediatek.c -- 2.25.1
[RFC v2 net-next 1/4] net: phy: add MediaTek PHY driver
Add support for MediaTek PHYs found in MT7530 and MT7531 switches. The initialization procedure is from the vendor driver, but due to lack of documentation, the function of some register values remains unknown. Signed-off-by: DENG Qingfang --- RFC v1 -> RFC v2: - Add PHY interface mode check, suggested by Andrew. drivers/net/phy/Kconfig| 5 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/mediatek.c | 112 + 3 files changed, 118 insertions(+) create mode 100644 drivers/net/phy/mediatek.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index a615b3660b05..edd858cec9ec 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -207,6 +207,11 @@ config MARVELL_88X_PHY Support for the Marvell 88X Dual-port Multi-speed Ethernet Transceiver. +config MEDIATEK_PHY + tristate "MediaTek PHYs" + help + Supports the MediaTek switch integrated PHYs. + config MICREL_PHY tristate "Micrel PHYs" help diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index de683e3abe63..9ed7dbab7770 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_LXT_PHY) += lxt.o obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o obj-$(CONFIG_MARVELL_PHY) += marvell.o obj-$(CONFIG_MARVELL_88X_PHY) += marvell-88x.o +obj-$(CONFIG_MEDIATEK_PHY) += mediatek.o obj-$(CONFIG_MESON_GXL_PHY)+= meson-gxl.o obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o obj-$(CONFIG_MICREL_PHY) += micrel.o diff --git a/drivers/net/phy/mediatek.c b/drivers/net/phy/mediatek.c new file mode 100644 index ..1faed57e2ed9 --- /dev/null +++ b/drivers/net/phy/mediatek.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include + +#define MTK_EXT_PAGE_ACCESS0x1f +#define MTK_PHY_PAGE_STANDARD 0x +#define MTK_PHY_PAGE_EXTENDED 0x0001 +#define MTK_PHY_PAGE_EXTENDED_20x0002 +#define MTK_PHY_PAGE_EXTENDED_30x0003 +#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 +#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 + +static int mtk_phy_read_page(struct phy_device *phydev) +{ + return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); +} + +static int mtk_phy_write_page(struct phy_device *phydev, int page) +{ + return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); +} + +static void mtk_phy_config_init(struct phy_device *phydev) +{ + /* Disable EEE */ + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); + + /* Enable HW auto downshift */ + phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4)); + + /* Increase SlvDPSready time */ + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); + __phy_write(phydev, 0x10, 0xafae); + __phy_write(phydev, 0x12, 0x2f); + __phy_write(phydev, 0x10, 0x8fae); + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); + + /* Adjust 100_mse_threshold */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0x); + + /* Disable mcc */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300); +} + +static int mt7530_phy_config_init(struct phy_device *phydev) +{ + mtk_phy_config_init(phydev); + + /* Increase post_update_timer */ + phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b); + + return 0; +} + +static int mt7531_phy_config_init(struct phy_device *phydev) +{ + if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL) + return -EINVAL; + + mtk_phy_config_init(phydev); + + /* PHY link down power saving enable */ + phy_set_bits(phydev, 0x17, BIT(4)); + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300); + + /* Set TX Pair delay selection */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); + + return 0; +} + +static struct phy_driver mtk_phy_driver[] = { + { + PHY_ID_MATCH_EXACT(0x03a29412), + .name = "MediaTek MT7530 PHY", + .config_init= mt7530_phy_config_init, + /* Interrupts are handled by the switch, not the PHY +* itself. +*/ + .config_intr= genphy_no_config_intr, + .handle_interrupt = genphy_handle_interrupt_no_ack, + .read_page = mtk_phy_read_page, + .write_page = mtk_phy_write_page, + }, + { + PHY_ID_MATCH_EXACT(0x03a29441), + .name = "MediaTek MT7531 PHY", + .config_init= mt7531_phy_config_init, + /* Interrupts are handled by the switch, not the PHY +* itself. +*/ + .config_intr= genphy_no_config_intr, + .handle_interrupt =
[PATCH v3 10/10] erofs: enable big pcluster feature
From: Gao Xiang Enable COMPR_CFGS and BIG_PCLUSTER since the implementations are all settled properly. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/erofs_fs.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h index ecc3a0ea0bc4..8739d3adf51f 100644 --- a/fs/erofs/erofs_fs.h +++ b/fs/erofs/erofs_fs.h @@ -20,7 +20,10 @@ #define EROFS_FEATURE_INCOMPAT_LZ4_0PADDING0x0001 #define EROFS_FEATURE_INCOMPAT_COMPR_CFGS 0x0002 #define EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER0x0002 -#define EROFS_ALL_FEATURE_INCOMPAT EROFS_FEATURE_INCOMPAT_LZ4_0PADDING +#define EROFS_ALL_FEATURE_INCOMPAT \ + (EROFS_FEATURE_INCOMPAT_LZ4_0PADDING | \ +EROFS_FEATURE_INCOMPAT_COMPR_CFGS | \ +EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER) #define EROFS_SB_EXTSLOT_SIZE 16 -- 2.20.1
[PATCH v3 09/10] erofs: support decompress big pcluster for lz4 backend
From: Gao Xiang Prior to big pcluster, there was only one compressed page so it'd easy to map this. However, when big pcluster is enabled, more work needs to be done to handle multiple compressed pages. In detail, - (maptype 0) if there is only one compressed page + no need to copy inplace I/O, just map it directly what we did before; - (maptype 1) if there are more compressed pages + no need to copy inplace I/O, vmap such compressed pages instead; - (maptype 2) if inplace I/O needs to be copied, use per-CPU buffers for decompression then. Another thing is how to detect inplace decompression is feasable or not (it's still quite easy for non big pclusters), apart from the inplace margin calculation, inplace I/O page reusing order is also needed to be considered for each compressed page. Currently, if the compressed page is the xth page, it shouldn't be reused as [0 ... nrpages_out - nrpages_in + x], otherwise a full copy will be triggered. Although there are some extra optimization ideas for this, I'd like to make big pcluster work correctly first and obviously it can be further optimized later since it has nothing with the on-disk format at all. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/decompressor.c | 217 +++- fs/erofs/internal.h | 15 +++ 2 files changed, 138 insertions(+), 94 deletions(-) diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 900de4725d35..ff15461b389d 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -120,44 +120,84 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq, return kaddr ? 1 : 0; } -static void *generic_copy_inplace_data(struct z_erofs_decompress_req *rq, - u8 *src, unsigned int pageofs_in) +static void *z_erofs_handle_inplace_io(struct z_erofs_decompress_req *rq, + void *inpage, unsigned int *inputmargin, int *maptype, + bool support_0padding) { - /* -* if in-place decompression is ongoing, those decompressed -* pages should be copied in order to avoid being overlapped. -*/ - struct page **in = rq->in; - u8 *const tmp = erofs_get_pcpubuf(1); - u8 *tmpp = tmp; - unsigned int inlen = rq->inputsize - pageofs_in; - unsigned int count = min_t(uint, inlen, PAGE_SIZE - pageofs_in); - - while (tmpp < tmp + inlen) { - if (!src) - src = kmap_atomic(*in); - memcpy(tmpp, src + pageofs_in, count); - kunmap_atomic(src); - src = NULL; - tmpp += count; - pageofs_in = 0; - count = PAGE_SIZE; + unsigned int nrpages_in, nrpages_out; + unsigned int ofull, oend, inputsize, total, i, j; + struct page **in; + void *src, *tmp; + + inputsize = rq->inputsize; + nrpages_in = PAGE_ALIGN(inputsize) >> PAGE_SHIFT; + oend = rq->pageofs_out + rq->outputsize; + ofull = PAGE_ALIGN(oend); + nrpages_out = ofull >> PAGE_SHIFT; + + if (rq->inplace_io) { + if (rq->partial_decoding || !support_0padding || + ofull - oend < LZ4_DECOMPRESS_INPLACE_MARGIN(inputsize)) + goto docopy; + + for (i = 0; i < nrpages_in; ++i) { + DBG_BUGON(rq->in[i] == NULL); + for (j = 0; j < nrpages_out - nrpages_in + i; ++j) + if (rq->out[j] == rq->in[i]) + goto docopy; + } + } + + if (nrpages_in <= 1) { + *maptype = 0; + return inpage; + } + kunmap_atomic(inpage); + might_sleep(); + src = erofs_vm_map_ram(rq->in, nrpages_in); + if (!src) + return ERR_PTR(-ENOMEM); + *maptype = 1; + return src; + +docopy: + /* Or copy compressed data which can be overlapped to per-CPU buffer */ + in = rq->in; + src = erofs_get_pcpubuf(nrpages_in); + if (!src) { + DBG_BUGON(1); + return ERR_PTR(-EFAULT); + } + + tmp = src; + total = rq->inputsize; + while (total) { + unsigned int page_copycnt = + min_t(unsigned int, total, PAGE_SIZE - *inputmargin); + + if (!inpage) + inpage = kmap_atomic(*in); + memcpy(tmp, inpage + *inputmargin, page_copycnt); + kunmap_atomic(inpage); + inpage = NULL; + tmp += page_copycnt; + total -= page_copycnt; ++in; + *inputmargin = 0; } - return tmp; + *maptype = 2; + return src; } static int z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq, u8 *out) { - unsigned int inputmargin, inlen; -
[PATCH v3 08/10] erofs: support parsing big pcluster compact indexes
From: Gao Xiang Different from non-compact indexes, several lclusters are packed as the compact form at once and an unique base blkaddr is stored for each pack, so each lcluster index would take less space on avarage (e.g. 2 bytes for COMPACT_2B.) btw, that is also why BIG_PCLUSTER switch should be consistent for compact head0/1. Prior to big pcluster, the size of all pclusters was 1 lcluster. Therefore, when a new HEAD lcluster was scanned, blkaddr would be bumped by 1 lcluster. However, that way doesn't work anymore for big pcluster since we actually don't know the compressed size of pclusters in advance (before reading CBLKCNT lcluster). So, instead, let blkaddr of each pack be the first pcluster blkaddr with a valid CBLKCNT, in detail, 1) if CBLKCNT starts at the pack, this first valid pcluster is itself, e.g. _ |_CBLKCNT0_|_NONHEAD_| .. |_HEAD_|_CBLKCNT1_| ... |_HEAD_| ... ^ = blkaddr base ^ += CBLKCNT0 ^ += CBLKCNT1 2) if CBLKCNT doesn't start at the pack, the first valid pcluster is the next pcluster, e.g. _ | NONHEAD_| .. |_HEAD_|_CBLKCNT0_| ... |_HEAD_|_HEAD_| ... ^ = blkaddr base^ += CBLKCNT0 ^ += 1 When a CBLKCNT is found, blkaddr will be increased by CBLKCNT lclusters, or a new HEAD is found immediately, bump blkaddr by 1 instead (see the picture above.) Also noted if CBLKCNT is the end of the pack, instead of storing delta1 (distance of the next HEAD lcluster) as normal NONHEADs, it still uses the compressed block count (delta0) since delta1 can be calculated indirectly but the block count can't. Adjust decoding logic to fit big pcluster compact indexes as well. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/zmap.c | 72 ++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 6c0c47f68b75..e62d813756f2 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -77,6 +77,22 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) } vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); + if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && + vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | + Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { + erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", + vi->nid); + err = -EFSCORRUPTED; + goto unmap_done; + } + if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && + !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ + !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { + erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", + vi->nid); + err = -EFSCORRUPTED; + goto unmap_done; + } /* paired with smp_mb() at the beginning of the function */ smp_mb(); set_bit(EROFS_I_Z_INITED_BIT, >flags); @@ -207,6 +223,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, unsigned int vcnt, base, lo, encodebits, nblk; int i; u8 *in, type; + bool big_pcluster; if (1 << amortizedshift == 4) vcnt = 2; @@ -215,6 +232,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, else return -EOPNOTSUPP; + big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1; encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; base = round_down(eofs, vcnt << amortizedshift); in = m->kaddr + base; @@ -226,7 +244,15 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, m->type = type; if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) { m->clusterofs = 1 << lclusterbits; - if (i + 1 != vcnt) { + if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) { + if (!big_pcluster) { + DBG_BUGON(1); + return -EFSCORRUPTED; + } + m->compressedlcs = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT; + m->delta[0] = 1; + return 0; + } else if (i + 1 != (int)vcnt) { m->delta[0] = lo; return 0; } @@ -239,22 +265,48 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, in, encodebits * (i - 1), ); if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) lo = 0; + else if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) + lo = 1;
[PATCH v3 07/10] erofs: support parsing big pcluster compress indexes
From: Gao Xiang When INCOMPAT_BIG_PCLUSTER sb feature is enabled, legacy compress indexes will also have the same on-disk header compact indexes to keep per-file configurations instead of leaving it zeroed. If ADVISE_BIG_PCLUSTER is set for a file, CBLKCNT will be loaded for each pcluster in this file by parsing 1st non-head lcluster. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/zmap.c | 79 + 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 7fd6bd843471..6c0c47f68b75 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -11,8 +11,10 @@ int z_erofs_fill_inode(struct inode *inode) { struct erofs_inode *const vi = EROFS_I(inode); + struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); - if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { + if (!erofs_sb_has_big_pcluster(sbi) && + vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { vi->z_advise = 0; vi->z_algorithmtype[0] = 0; vi->z_algorithmtype[1] = 0; @@ -49,7 +51,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) if (test_bit(EROFS_I_Z_INITED_BIT, >flags)) goto out_unlock; - DBG_BUGON(vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY); + DBG_BUGON(!erofs_sb_has_big_pcluster(EROFS_SB(sb)) && + vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY); pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + vi->xattr_isize, 8); @@ -96,7 +99,7 @@ struct z_erofs_maprecorder { u8 type; u16 clusterofs; u16 delta[2]; - erofs_blk_t pblk; + erofs_blk_t pblk, compressedlcs; }; static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m, @@ -159,6 +162,15 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m, case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: m->clusterofs = 1 << vi->z_logical_clusterbits; m->delta[0] = le16_to_cpu(di->di_u.delta[0]); + if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) { + if (!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) { + DBG_BUGON(1); + return -EFSCORRUPTED; + } + m->compressedlcs = m->delta[0] & + ~Z_EROFS_VLE_DI_D0_CBLKCNT; + m->delta[0] = 1; + } m->delta[1] = le16_to_cpu(di->di_u.delta[1]); break; case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: @@ -366,6 +378,58 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, return 0; } +static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m, + unsigned int initial_lcn) +{ + struct erofs_inode *const vi = EROFS_I(m->inode); + struct erofs_map_blocks *const map = m->map; + const unsigned int lclusterbits = vi->z_logical_clusterbits; + unsigned long lcn; + int err; + + DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN && + m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD); + if (!(map->m_flags & EROFS_MAP_ZIPPED) || + !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) { + map->m_plen = 1 << lclusterbits; + return 0; + } + + lcn = m->lcn + 1; + if (m->compressedlcs) + goto out; + if (lcn == initial_lcn) + goto err_bonus_cblkcnt; + + err = z_erofs_load_cluster_from_disk(m, lcn); + if (err) + return err; + + switch (m->type) { + case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: + if (m->delta[0] != 1) + goto err_bonus_cblkcnt; + if (m->compressedlcs) + break; + fallthrough; + default: + erofs_err(m->inode->i_sb, + "cannot found CBLKCNT @ lcn %lu of nid %llu", + lcn, vi->nid); + DBG_BUGON(1); + return -EFSCORRUPTED; + } +out: + map->m_plen = m->compressedlcs << lclusterbits; + return 0; +err_bonus_cblkcnt: + erofs_err(m->inode->i_sb, + "bogus CBLKCNT @ lcn %lu of nid %llu", + lcn, vi->nid); + DBG_BUGON(1); + return -EFSCORRUPTED; +} + int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, int flags) @@ -377,6 +441,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, }; int err = 0; unsigned int lclusterbits, endoff; + unsigned long initial_lcn; unsigned long long ofs, end; trace_z_erofs_map_blocks_iter_enter(inode, map, flags); @@
[PATCH v3 06/10] erofs: adjust per-CPU buffers according to max_pclusterblks
From: Gao Xiang Adjust per-CPU buffers on demand since big pcluster definition is available. Also, bail out unsupported pcluster size according to Z_EROFS_PCLUSTER_MAX_SIZE. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/decompressor.c | 20 fs/erofs/internal.h | 2 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index fb4838c0f0df..900de4725d35 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -32,6 +32,7 @@ int z_erofs_load_lz4_config(struct super_block *sb, struct erofs_super_block *dsb, struct z_erofs_lz4_cfgs *lz4, int size) { + struct erofs_sb_info *sbi = EROFS_SB(sb); u16 distance; if (lz4) { @@ -40,16 +41,27 @@ int z_erofs_load_lz4_config(struct super_block *sb, return -EINVAL; } distance = le16_to_cpu(lz4->max_distance); + + sbi->lz4.max_pclusterblks = le16_to_cpu(lz4->max_pclusterblks); + if (!sbi->lz4.max_pclusterblks) { + sbi->lz4.max_pclusterblks = 1; /* reserved case */ + } else if (sbi->lz4.max_pclusterblks > + Z_EROFS_PCLUSTER_MAX_SIZE / EROFS_BLKSIZ) { + erofs_err(sb, "too large lz4 pclusterblks %u", + sbi->lz4.max_pclusterblks); + return -EINVAL; + } else if (sbi->lz4.max_pclusterblks >= 2) { + erofs_info(sb, "EXPERIMENTAL big pcluster feature in use. Use at your own risk!"); + } } else { distance = le16_to_cpu(dsb->u1.lz4_max_distance); + sbi->lz4.max_pclusterblks = 1; } - EROFS_SB(sb)->lz4.max_distance_pages = distance ? + sbi->lz4.max_distance_pages = distance ? DIV_ROUND_UP(distance, PAGE_SIZE) + 1 : LZ4_MAX_DISTANCE_PAGES; - - /* TODO: use max pclusterblks after bigpcluster is enabled */ - return erofs_pcpubuf_growsize(1); + return erofs_pcpubuf_growsize(sbi->lz4.max_pclusterblks); } static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq, diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index c4b3938a7e56..f1305af50f67 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -63,6 +63,8 @@ struct erofs_fs_context { struct erofs_sb_lz4_info { /* # of pages needed for EROFS lz4 rolling decompression */ u16 max_distance_pages; + /* maximum possible blocks for pclusters in the filesystem */ + u16 max_pclusterblks; }; struct erofs_sb_info { -- 2.20.1
[PATCH v3 05/10] erofs: add big physical cluster definition
From: Gao Xiang Big pcluster indicates the size of compressed data for each physical pcluster is no longer fixed as block size, but could be more than 1 block (more accurately, 1 logical pcluster) When big pcluster feature is enabled for head0/1, delta0 of the 1st non-head lcluster index will keep block count of this pcluster in lcluster size instead of 1. Or, the compressed size of pcluster should be 1 lcluster if pcluster has no non-head lcluster index. Also note that BIG_PCLUSTER feature reuses COMPR_CFGS feature since it depends on COMPR_CFGS and will be released together. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/erofs_fs.h | 19 +++ fs/erofs/internal.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h index 76777673eb63..ecc3a0ea0bc4 100644 --- a/fs/erofs/erofs_fs.h +++ b/fs/erofs/erofs_fs.h @@ -19,6 +19,7 @@ */ #define EROFS_FEATURE_INCOMPAT_LZ4_0PADDING0x0001 #define EROFS_FEATURE_INCOMPAT_COMPR_CFGS 0x0002 +#define EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER0x0002 #define EROFS_ALL_FEATURE_INCOMPAT EROFS_FEATURE_INCOMPAT_LZ4_0PADDING #define EROFS_SB_EXTSLOT_SIZE 16 @@ -214,17 +215,20 @@ enum { /* 14 bytes (+ length field = 16 bytes) */ struct z_erofs_lz4_cfgs { __le16 max_distance; - u8 reserved[12]; + __le16 max_pclusterblks; + u8 reserved[10]; } __packed; /* * bit 0 : COMPACTED_2B indexes (0 - off; 1 - on) * e.g. for 4k logical cluster size, 4Bif compacted 2B is off; * (4B) + 2B + (4B) if compacted 2B is on. + * bit 1 : HEAD1 big pcluster (0 - off; 1 - on) + * bit 2 : HEAD2 big pcluster (0 - off; 1 - on) */ -#define Z_EROFS_ADVISE_COMPACTED_2B_BIT 0 - -#define Z_EROFS_ADVISE_COMPACTED_2B (1 << Z_EROFS_ADVISE_COMPACTED_2B_BIT) +#define Z_EROFS_ADVISE_COMPACTED_2B0x0001 +#define Z_EROFS_ADVISE_BIG_PCLUSTER_1 0x0002 +#define Z_EROFS_ADVISE_BIG_PCLUSTER_2 0x0004 struct z_erofs_map_header { __le32 h_reserved1; @@ -279,6 +283,13 @@ enum { #define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS2 #define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT 0 +/* + * D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the + * compressed block count of a compressed extent (in logical clusters, aka. + * block count of a pcluster). + */ +#define Z_EROFS_VLE_DI_D0_CBLKCNT (1 << 11) + struct z_erofs_vle_decompressed_index { __le16 di_advise; /* where to decompress in the head cluster */ diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 06c294929069..c4b3938a7e56 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -230,6 +230,7 @@ static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \ EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_LZ4_0PADDING) EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS) +EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER) EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM) /* atomic flag definitions */ -- 2.20.1
[PATCH v3 04/10] erofs: fix up inplace I/O pointer for big pcluster
From: Gao Xiang When picking up inplace I/O pages, it should be traversed in reverse order in aligned with the traversal order of file-backed online pages. Also, index should be updated together when preloading compressed pages. Previously, only page-sized pclustersize was supported so no problem at all. Also rename `compressedpages' to `icpage_ptr' to reflect its functionality. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/zdata.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index db296d324333..78e4b598ecca 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -204,7 +204,8 @@ struct z_erofs_collector { struct z_erofs_pcluster *pcl, *tailpcl; struct z_erofs_collection *cl; - struct page **compressedpages; + /* a pointer used to pick up inplace I/O pages */ + struct page **icpage_ptr; z_erofs_next_pcluster_t owned_head; enum z_erofs_collectmode mode; @@ -238,17 +239,19 @@ static void preload_compressed_pages(struct z_erofs_collector *clt, enum z_erofs_cache_alloctype type, struct list_head *pagepool) { - const struct z_erofs_pcluster *pcl = clt->pcl; - struct page **pages = clt->compressedpages; - pgoff_t index = pcl->obj.index + (pages - pcl->compressed_pages); + struct z_erofs_pcluster *pcl = clt->pcl; bool standalone = true; gfp_t gfp = (mapping_gfp_mask(mc) & ~__GFP_DIRECT_RECLAIM) | __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN; + struct page **pages; + pgoff_t index; if (clt->mode < COLLECT_PRIMARY_FOLLOWED) return; - for (; pages < pcl->compressed_pages + pcl->pclusterpages; ++pages) { + pages = pcl->compressed_pages; + index = pcl->obj.index; + for (; index < pcl->obj.index + pcl->pclusterpages; ++index, ++pages) { struct page *page; compressed_page_t t; struct page *newpage = NULL; @@ -360,16 +363,14 @@ int erofs_try_to_free_cached_page(struct address_space *mapping, } /* page_type must be Z_EROFS_PAGE_TYPE_EXCLUSIVE */ -static inline bool z_erofs_try_inplace_io(struct z_erofs_collector *clt, - struct page *page) +static bool z_erofs_try_inplace_io(struct z_erofs_collector *clt, + struct page *page) { struct z_erofs_pcluster *const pcl = clt->pcl; - while (clt->compressedpages < - pcl->compressed_pages + pcl->pclusterpages) { - if (!cmpxchg(clt->compressedpages++, NULL, page)) + while (clt->icpage_ptr > pcl->compressed_pages) + if (!cmpxchg(--clt->icpage_ptr, NULL, page)) return true; - } return false; } @@ -576,9 +577,8 @@ static int z_erofs_collector_begin(struct z_erofs_collector *clt, z_erofs_pagevec_ctor_init(>vector, Z_EROFS_NR_INLINE_PAGEVECS, clt->cl->pagevec, clt->cl->vcnt); - clt->compressedpages = clt->pcl->compressed_pages; - if (clt->mode <= COLLECT_PRIMARY) /* cannot do in-place I/O */ - clt->compressedpages += clt->pcl->pclusterpages; + /* since file-backed online pages are traversed in reverse order */ + clt->icpage_ptr = clt->pcl->compressed_pages + clt->pcl->pclusterpages; return 0; } -- 2.20.1
[PATCH v3 03/10] erofs: introduce physical cluster slab pools
From: Gao Xiang Since multiple pcluster sizes could be used at once, the number of compressed pages will become a variable factor. It's necessary to introduce slab pools rather than a single slab cache now. This limits the pclustersize to 1M (Z_EROFS_PCLUSTER_MAX_SIZE), and get rid of the obsolete EROFS_FS_CLUSTER_PAGE_LIMIT, which has no use now. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/Kconfig| 14 fs/erofs/erofs_fs.h | 3 + fs/erofs/internal.h | 3 - fs/erofs/zdata.c| 172 +--- fs/erofs/zdata.h| 14 ++-- 5 files changed, 126 insertions(+), 80 deletions(-) diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig index 74b0aaa7114c..858b3339f381 100644 --- a/fs/erofs/Kconfig +++ b/fs/erofs/Kconfig @@ -76,17 +76,3 @@ config EROFS_FS_ZIP If you don't want to enable compression feature, say N. -config EROFS_FS_CLUSTER_PAGE_LIMIT - int "EROFS Cluster Pages Hard Limit" - depends on EROFS_FS_ZIP - range 1 256 - default "1" - help - Indicates maximum # of pages of a compressed - physical cluster. - - For example, if files in a image were compressed - into 8k-unit, hard limit should not be configured - less than 2. Otherwise, the image will be refused - to mount on this kernel. - diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h index 626b7d3e9ab7..76777673eb63 100644 --- a/fs/erofs/erofs_fs.h +++ b/fs/erofs/erofs_fs.h @@ -201,6 +201,9 @@ static inline unsigned int erofs_xattr_entry_size(struct erofs_xattr_entry *e) e->e_name_len + le16_to_cpu(e->e_value_size)); } +/* maximum supported size of a physical compression cluster */ +#define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024) + /* available compression algorithm types (for h_algorithmtype) */ enum { Z_EROFS_COMPRESSION_LZ4 = 0, diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index f707d28a46d9..06c294929069 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -194,9 +194,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) return v; } #endif /* !CONFIG_SMP */ - -/* hard limit of pages per compressed cluster */ -#define Z_EROFS_CLUSTER_MAX_PAGES (CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT) #endif /* !CONFIG_EROFS_FS_ZIP */ /* we strictly follow PAGE_SIZE and no buffer head yet */ diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index e3f0100d82d1..db296d324333 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -10,6 +10,93 @@ #include +/* + * since pclustersize is variable for big pcluster feature, introduce slab + * pools implementation for different pcluster sizes. + */ +struct z_erofs_pcluster_slab { + struct kmem_cache *slab; + unsigned int maxpages; + char name[48]; +}; + +#define _PCLP(n) { .maxpages = n } + +static struct z_erofs_pcluster_slab pcluster_pool[] __read_mostly = { + _PCLP(1), _PCLP(4), _PCLP(16), _PCLP(64), _PCLP(128), + _PCLP(Z_EROFS_PCLUSTER_MAX_PAGES) +}; + +static void z_erofs_destroy_pcluster_pool(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcluster_pool); ++i) { + if (!pcluster_pool[i].slab) + continue; + kmem_cache_destroy(pcluster_pool[i].slab); + pcluster_pool[i].slab = NULL; + } +} + +static int z_erofs_create_pcluster_pool(void) +{ + struct z_erofs_pcluster_slab *pcs; + struct z_erofs_pcluster *a; + unsigned int size; + + for (pcs = pcluster_pool; +pcs < pcluster_pool + ARRAY_SIZE(pcluster_pool); ++pcs) { + size = struct_size(a, compressed_pages, pcs->maxpages); + + sprintf(pcs->name, "erofs_pcluster-%u", pcs->maxpages); + pcs->slab = kmem_cache_create(pcs->name, size, 0, + SLAB_RECLAIM_ACCOUNT, NULL); + if (pcs->slab) + continue; + + z_erofs_destroy_pcluster_pool(); + return -ENOMEM; + } + return 0; +} + +static struct z_erofs_pcluster *z_erofs_alloc_pcluster(unsigned int nrpages) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcluster_pool); ++i) { + struct z_erofs_pcluster_slab *pcs = pcluster_pool + i; + struct z_erofs_pcluster *pcl; + + if (nrpages > pcs->maxpages) + continue; + + pcl = kmem_cache_zalloc(pcs->slab, GFP_NOFS); + if (!pcl) + return ERR_PTR(-ENOMEM); + pcl->pclusterpages = nrpages; + return pcl; + } + return ERR_PTR(-EINVAL); +} + +static void z_erofs_free_pcluster(struct z_erofs_pcluster *pcl) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcluster_pool); ++i) { + struct z_erofs_pcluster_slab *pcs = pcluster_pool + i; + +
[PATCH v3 02/10] erofs: introduce multipage per-CPU buffers
From: Gao Xiang To deal the with the cases which inplace decompression is infeasible for some inplace I/O. Per-CPU buffers was introduced to get rid of page allocation latency and thrash for low-latency decompression algorithms such as lz4. For the big pcluster feature, introduce multipage per-CPU buffers to keep such inplace I/O pclusters temporarily as well but note that per-CPU pages are just consecutive virtually. When a new big pcluster fs is mounted, its max pclustersize will be read and per-CPU buffers can be growed if needed. Shrinking adjustable per-CPU buffers is more complex (because we don't know if such size is still be used), so currently just release them all when unloading. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/Makefile | 2 +- fs/erofs/decompressor.c | 8 ++- fs/erofs/internal.h | 24 ++- fs/erofs/pcpubuf.c | 134 fs/erofs/super.c| 1 + fs/erofs/utils.c| 12 6 files changed, 147 insertions(+), 34 deletions(-) create mode 100644 fs/erofs/pcpubuf.c diff --git a/fs/erofs/Makefile b/fs/erofs/Makefile index af159539fc1b..1f9aced49070 100644 --- a/fs/erofs/Makefile +++ b/fs/erofs/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_EROFS_FS) += erofs.o -erofs-objs := super.o inode.o data.o namei.o dir.o utils.o +erofs-objs := super.o inode.o data.o namei.o dir.o utils.o pcpubuf.o erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o erofs-$(CONFIG_EROFS_FS_ZIP) += decompressor.o zmap.o zdata.o diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 27aa6a99b371..fb4838c0f0df 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -47,7 +47,9 @@ int z_erofs_load_lz4_config(struct super_block *sb, EROFS_SB(sb)->lz4.max_distance_pages = distance ? DIV_ROUND_UP(distance, PAGE_SIZE) + 1 : LZ4_MAX_DISTANCE_PAGES; - return 0; + + /* TODO: use max pclusterblks after bigpcluster is enabled */ + return erofs_pcpubuf_growsize(1); } static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq, @@ -114,7 +116,7 @@ static void *generic_copy_inplace_data(struct z_erofs_decompress_req *rq, * pages should be copied in order to avoid being overlapped. */ struct page **in = rq->in; - u8 *const tmp = erofs_get_pcpubuf(0); + u8 *const tmp = erofs_get_pcpubuf(1); u8 *tmpp = tmp; unsigned int inlen = rq->inputsize - pageofs_in; unsigned int count = min_t(uint, inlen, PAGE_SIZE - pageofs_in); @@ -271,7 +273,7 @@ static int z_erofs_decompress_generic(struct z_erofs_decompress_req *rq, * compressed data is preferred. */ if (rq->outputsize <= PAGE_SIZE * 7 / 8) { - dst = erofs_get_pcpubuf(0); + dst = erofs_get_pcpubuf(1); if (IS_ERR(dst)) return PTR_ERR(dst); diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 05b02f99324c..f707d28a46d9 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -197,9 +197,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) /* hard limit of pages per compressed cluster */ #define Z_EROFS_CLUSTER_MAX_PAGES (CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT) -#define EROFS_PCPUBUF_NR_PAGES Z_EROFS_CLUSTER_MAX_PAGES -#else -#define EROFS_PCPUBUF_NR_PAGES 0 #endif /* !CONFIG_EROFS_FS_ZIP */ /* we strictly follow PAGE_SIZE and no buffer head yet */ @@ -405,24 +402,15 @@ int erofs_namei(struct inode *dir, struct qstr *name, /* dir.c */ extern const struct file_operations erofs_dir_fops; +/* pcpubuf.c */ +void *erofs_get_pcpubuf(unsigned int requiredpages); +void erofs_put_pcpubuf(void *ptr); +int erofs_pcpubuf_growsize(unsigned int nrpages); +void erofs_pcpubuf_exit(void); + /* utils.c / zdata.c */ struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp); -#if (EROFS_PCPUBUF_NR_PAGES > 0) -void *erofs_get_pcpubuf(unsigned int pagenr); -#define erofs_put_pcpubuf(buf) do { \ - (void)&(buf); \ - preempt_enable(); \ -} while (0) -#else -static inline void *erofs_get_pcpubuf(unsigned int pagenr) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -#define erofs_put_pcpubuf(buf) do {} while (0) -#endif - #ifdef CONFIG_EROFS_FS_ZIP int erofs_workgroup_put(struct erofs_workgroup *grp); struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, diff --git a/fs/erofs/pcpubuf.c b/fs/erofs/pcpubuf.c new file mode 100644 index ..b4b10ea8babf --- /dev/null +++ b/fs/erofs/pcpubuf.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) Gao Xiang + * + * For low-latency decompression algorithms (e.g. lz4), reserve consecutive + * per-CPU virtual memory (in pages) in advance to store such inplace I/O + * data if inplace
[PATCH v3 01/10] erofs: reserve physical_clusterbits[]
From: Gao Xiang Formal big pcluster design is actually more powerful / flexable than the previous thought whose pclustersize was fixed as power-of-2 blocks, which was obviously inefficient and space-wasting. Instead, pclustersize can now be set independently for each pcluster, so various pcluster sizes can also be used together in one file if mkfs wants (for example, according to data type and/or compression ratio). Let's get rid of previous physical_clusterbits[] setting (also notice that corresponding on-disk fields are still 0 for now). Therefore, head1/2 can be used for at most 2 different algorithms in one file and again pclustersize is now independent of these. Acked-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/erofs_fs.h | 4 +--- fs/erofs/internal.h | 1 - fs/erofs/zdata.c| 3 +-- fs/erofs/zmap.c | 15 --- 4 files changed, 2 insertions(+), 21 deletions(-) diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h index 17bc0b5f117d..626b7d3e9ab7 100644 --- a/fs/erofs/erofs_fs.h +++ b/fs/erofs/erofs_fs.h @@ -233,9 +233,7 @@ struct z_erofs_map_header { __u8h_algorithmtype; /* * bit 0-2 : logical cluster bits - 12, e.g. 0 for 4096; -* bit 3-4 : (physical - logical) cluster bits of head 1: -* For example, if logical clustersize = 4096, 1 for 8192. -* bit 5-7 : (physical - logical) cluster bits of head 2. +* bit 3-7 : reserved. */ __u8h_clusterbits; }; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 6006391a..05b02f99324c 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -266,7 +266,6 @@ struct erofs_inode { unsigned short z_advise; unsigned char z_algorithmtype[2]; unsigned char z_logical_clusterbits; - unsigned char z_physical_clusterbits[2]; }; #endif /* CONFIG_EROFS_FS_ZIP */ }; diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index 4226f4115981..e3f0100d82d1 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -430,8 +430,7 @@ static int z_erofs_register_collection(struct z_erofs_collector *clt, else pcl->algorithmformat = Z_EROFS_COMPRESSION_SHIFTED; - pcl->clusterbits = EROFS_I(inode)->z_physical_clusterbits[0]; - pcl->clusterbits -= PAGE_SHIFT; + pcl->clusterbits = 0; /* new pclusters should be claimed as type 1, primary and followed */ pcl->next = clt->owned_head; diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index b384f546d368..7fd6bd843471 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -17,11 +17,8 @@ int z_erofs_fill_inode(struct inode *inode) vi->z_algorithmtype[0] = 0; vi->z_algorithmtype[1] = 0; vi->z_logical_clusterbits = LOG_BLOCK_SIZE; - vi->z_physical_clusterbits[0] = vi->z_logical_clusterbits; - vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits; set_bit(EROFS_I_Z_INITED_BIT, >flags); } - inode->i_mapping->a_ops = _erofs_aops; return 0; } @@ -77,18 +74,6 @@ static int z_erofs_fill_inode_lazy(struct inode *inode) } vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); - vi->z_physical_clusterbits[0] = vi->z_logical_clusterbits + - ((h->h_clusterbits >> 3) & 3); - - if (vi->z_physical_clusterbits[0] != LOG_BLOCK_SIZE) { - erofs_err(sb, "unsupported physical clusterbits %u for nid %llu, please upgrade kernel", - vi->z_physical_clusterbits[0], vi->nid); - err = -EOPNOTSUPP; - goto unmap_done; - } - - vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits + - ((h->h_clusterbits >> 5) & 7); /* paired with smp_mb() at the beginning of the function */ smp_mb(); set_bit(EROFS_I_Z_INITED_BIT, >flags); -- 2.20.1
[PATCH v3 00/10] erofs: add big pcluster compression support
Hi folks, This is the formal version of EROFS big pcluster support, which means EROFS can compress data into more than 1 fs block after this patchset. {l,p}cluster are EROFS-specific concepts, standing for `logical cluster' and `physical cluster' correspondingly. Logical cluster is the basic unit of compress indexes in file logical mapping, e.g. it can build compress indexes in 2 blocks rather than 1 block (currently only 1 block lcluster is supported). Physical cluster is a container of physical compressed blocks which contains compressed data, the size of which is the multiple of lclustersize. Different from previous thoughts, which had fixed-sized pclusterblks recorded in the on-disk compress index header, our on-disk design allows variable-sized pclusterblks now. The main reasons are - user data varies in compression ratio locally, so fixed-sized clustersize approach is space-wasting and causes extra read amplification for high CR cases; - inplace decompression needs zero padding to guarantee its safe margin, but we don't want to pad more than 1 fs block for big pcluster; - end users can now customize the pcluster size according to data type since various pclustersize can exist in a file, for example, using different pcluster size for executable code and one-shot data. such design should be more flexible than many other public compression fses (Btw, each file in EROFS can have maximum 2 algorithms at the same time by using HEAD1/2, which will be formally added with LZMA support.) In brief, EROFS can now compress from variable-sized input to variable-sized pcluster blocks, as illustrated below: |<-_lcluster_->||<-_lcluster_->| |._|_ .. ___|___.__| .. . . .__. |__| .. |__| |<- pcluster->| The next step would be how to record the compressed block count in lclusters. In compress indexes, there are 2 concepts called HEAD and NONHEAD lclusters. The difference is that HEAD lcluster starts a new pcluster in the lcluster, but NONHEAD not. It's easy to understand that big pclusters at least have 2 pclusters, thus at least 2 lclusters as well. Therefore, let the delta0 (distance to its HEAD lcluster) of first NONHEAD compress index store the compressed block count with a special flag as a new called CBLKCNT compress index. It's also easy to know its delta0 is constantly 1, as illustrated below: |_HEAD_|_CBLKCNT_|_NONHEAD_|_..._|_NONHEAD_|_HEAD | HEAD | |<-- a pcluster with CBLKCNT ->|<-- -->| ^ a pcluster with 1 If another HEAD follows a HEAD lcluster, there is no room to record CBLKCNT, but it's easy to know the size of pcluster will be 1. More implementation details about this and compact indexes are in the commit message. On the runtime performance side, the current EROFS test results are: | file system | size| seq read | rand read | rand9m read | |___|___|_ MiB/s __|__ MiB/s __|___ MiB/s ___| |___erofs_4k|_556879872_|_ 781.4 __|__ 55.3 ___|___ 25.3 ___| |___erofs_16k___|_452509696_|_ 864.8 __|_ 123.2 ___|___ 20.8 ___| |___erofs_32k___|_415223808_|_ 899.8 __|_ 105.8 _*_|___ 16.8 | |___erofs_64k___|_393814016_|_ 906.6 __|__ 66.6 _*_|___ 11.8 | |__squashfs_8k__|_556191744_|_ 64.9 __|__ 19.3 ___| 9.1 | |__squashfs_16k_|_502661120_|_ 98.9 __|__ 38.0 ___| 9.8 | |__squashfs_32k_|_458784768_|_ 115.4 __|__ 71.6 _*_|___ 10.0 | |_squashfs_128k_|_398204928_|_ 257.2 __|_ 253.8 _*_|___ 10.9 | |ext4_4k|()_|_ 786.6 __|__ 28.6 ___|___ 27.8 | * Squashfs grabs more page cache to keep all decompressed data with grab_cache_page_nowait() than the normal requested readahead (see squashfs_copy_cache and squashfs_readpage_block). In principle, EROFS can also cache such all decompressed data if necessary, yet it's low priority for now and has little use (rand9m is actually a better rand read workload, since the amount of I/O is 9m rather than full-sized 1000m). More details are in https://lore.kernel.org/r/20210329053654.ga3281...@xiangao.remote.csb Also it's easy to know EROFS is not a fixed pcluster design, so users can make several optimized strategy according to data type when mkfs. And there is still room to optimize runtime performance for big pcluster even further. Finally, it passes ro_fsstress and can also successfully boot buildroot & Android system with android-mainline repo. current mkfs repo for big pcluster: https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git -b experimental-bigpcluster-compact Thanks for
Re: [PATCH v3 3/3] input: gpio-keys: Use hrtimer for software debounce, if possible
On Tue, Apr 06, 2021 at 11:37:07AM +0300, Tony Lindgren wrote: > Hi, > > * Dmitry Torokhov [700101 02:00]: > > On Sun, Mar 07, 2021 at 10:22:40PM +, Paul Cercueil wrote: > > > We want to be able to report the input event as soon as the debounce > > > delay elapsed. However, the current code does not really ensure that, > > > as it uses the jiffies-based schedule_delayed_work() API. With a small > > > enough HZ value (HZ <= 100), this results in some input events being > > > lost, when a key is quickly pressed then released (on a human's time > > > scale). > > > > > > Switching to hrtimers fixes this issue, and will work even on extremely > > > low HZ values (tested at HZ=24). This is however only possible if > > > reading the GPIO is possible without sleeping. If this condition is not > > > met, the previous approach of using a jiffies-based timer is taken. > > > > > > Signed-off-by: Paul Cercueil > > > > Applied with minor edits to make more use of debounce_use_hrtimer flag. > > While testing Linux next I noticed that this patch causes a null pointer > dereference at least when unbinding a gpio-keys instance, see below. Ugh, my "minor edits" did screw things up ;( as I mixed up release and debounce timers. I'll fix it up. > > Regards, > > Tony > > 8< - > Unable to handle kernel NULL pointer dereference at virtual address 000c > ... > PC is at hrtimer_active+0xc/0x98 > LR is at hrtimer_try_to_cancel+0x24/0x140 > ... > [] (hrtimer_active) from [] > (hrtimer_try_to_cancel+0x24/0x140) > [] (hrtimer_try_to_cancel) from [] > (hrtimer_cancel+0x14/0x4c) > [] (hrtimer_cancel) from [] > (gpio_keys_attr_store_helper+0x1b8/0x1d8 [gpio_keys]) > [] (gpio_keys_attr_store_helper [gpio_keys]) from [] > (gpio_keys_store_disabled_keys+0x18/0x24 [gpio_keys]) > [] (gpio_keys_store_disabled_keys [gpio_keys]) from [] > (kernfs_fop_write_iter+0x10c/0x1cc) > [] (kernfs_fop_write_iter) from [] (vfs_write+0x2ac/0x404) > [] (vfs_write) from [] (ksys_write+0x64/0xdc) > [] (ksys_write) from [] (ret_fast_syscall+0x0/0x58) > -- Dmitry
[PATCH v2 3/3] arm64: dts: meson: add GPIO line names to ODROID N2/N2+
From: Hyeonki Hong Add GPIO line-name identifiers to the ODROID N2/N2+ common dtsi. Signed-off-by: Hyeonki Hong Signed-off-by: Christian Hewitt Reviewed-by: Neil Armstrong --- .../dts/amlogic/meson-g12b-odroid-n2.dtsi | 45 +++ 1 file changed, 45 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi index 0a994668e707..473b81c652cf 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi @@ -446,6 +446,51 @@ }; { + gpio-line-names = + /* GPIOZ */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* GPIOH */ + "", "", "", "", "", "", "", "", + "", + /* BOOT */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + /* GPIOC */ + "", "", "", "", "", "", "", "", + /* GPIOA */ + "PIN_44", /* GPIOA_0 */ + "PIN_46", /* GPIOA_1 */ + "PIN_45", /* GPIOA_2 */ + "PIN_47", /* GPIOA_3 */ + "PIN_26", /* GPIOA_4 */ + "", "", "", "", "", "", + "PIN_42", /* GPIOA_11 */ + "PIN_32", /* GPIOA_12 */ + "PIN_7", /* GPIOA_13 */ + "PIN_27", /* GPIOA_14 */ + "PIN_28", /* GPIOA_15 */ + /* GPIOX */ + "PIN_16", /* GPIOX_0 */ + "PIN_18", /* GPIOX_1 */ + "PIN_22", /* GPIOX_2 */ + "PIN_11", /* GPIOX_3 */ + "PIN_13", /* GPIOX_4 */ + "PIN_33", /* GPIOX_5 */ + "PIN_35", /* GPIOX_6 */ + "PIN_15", /* GPIOX_7 */ + "PIN_19", /* GPIOX_8 */ + "PIN_21", /* GPIOX_9 */ + "PIN_24", /* GPIOX_10 */ + "PIN_23", /* GPIOX_11 */ + "PIN_8", /* GPIOX_12 */ + "PIN_10", /* GPIOX_13 */ + "PIN_29", /* GPIOX_14 */ + "PIN_31", /* GPIOX_15 */ + "PIN_12", /* GPIOX_16 */ + "PIN_3", /* GPIOX_17 */ + "PIN_5", /* GPIOX_18 */ + "PIN_36"; /* GPIOX_19 */ /* * WARNING: The USB Hub on the Odroid-N2 needs a reset signal * to be turned high in order to be detected by the USB Controller -- 2.17.1
[PATCH v2 1/3] arm64: dts: meson: remove extra tab from ODROID N2/N2+ ext_mdio node
Remove an extra tab from the ext_mdio node in the ODROID N2/N2+ common dtsi file. Signed-off-by: Christian Hewitt Reviewed-by: Neil Armstrong Reviewed-by: Martin Blumenstingl --- arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi index 58ce569b2ace..2f8d574c30c0 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi @@ -410,7 +410,7 @@ _mdio { external_phy: ethernet-phy@0 { - /* Realtek RTL8211F (0x001cc916) */ + /* Realtek RTL8211F (0x001cc916) */ reg = <0>; max-speed = <1000>; -- 2.17.1
[PATCH v2 2/3] arm64: dts: meson: add saradc node to ODROID N2/N2+
From: Hyeonki Hong Add the meson saradc node to the ODROID N2/N2+ common dtsi. Signed-off-by: Hyeonki Hong Signed-off-by: Christian Hewitt --- arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi index 2f8d574c30c0..0a994668e707 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi @@ -508,6 +508,11 @@ status = "okay"; }; + { + status = "okay"; + vref-supply = <_1v8>; +}; + /* SD card */ _emmc_b { status = "okay"; -- 2.17.1
[PATCH v2 0/3] arm64: dts: meson: misc ODROID-N2/N2+ changes
This series cleans-up and submits some minor patches used in HardKernel Linux 5.10 and 5.11 images for the ODROID N2/N2+, and fixes a stray tab. Changes since v1: - Added reviewed-by's on patches 1/3 - Added my Signed-off-by to patches 2/3 - Added missing vref to patch 2 - Rebased on khilman/v5.13/dt64 Christian Hewitt (1): arm64: dts: meson: remove extra tab from ODROID N2/N2+ ext_mdio node Hyeonki Hong (2): arm64: dts: meson: add saradc node to ODROID N2/N2+ arm64: dts: meson: add GPIO line names to ODROID N2/N2+ .../dts/amlogic/meson-g12b-odroid-n2.dtsi | 52 ++- 1 file changed, 51 insertions(+), 1 deletion(-) -- 2.17.1
Re: rtlwifi/rtl8192cu AP mode broken with PS STA
On 4/6/21 9:48 PM, Pkshih wrote: On Tue, 2021-04-06 at 11:25 -0500, Larry Finger wrote: On 4/6/21 7:06 AM, Maciej S. Szmigiero wrote: On 06.04.2021 12:00, Kalle Valo wrote: "Maciej S. Szmigiero" writes: On 29.03.2021 00:54, Maciej S. Szmigiero wrote: Hi, It looks like rtlwifi/rtl8192cu AP mode is broken when a STA is using PS, since the driver does not update its beacon to account for TIM changes, so a station that is sleeping will never learn that it has packets buffered at the AP. Looking at the code, the rtl8192cu driver implements neither the set_tim() callback, nor does it explicitly update beacon data periodically, so it has no way to learn that it had changed. This results in the AP mode being virtually unusable with STAs that do PS and don't allow for it to be disabled (IoT devices, mobile phones, etc.). I think the easiest fix here would be to implement set_tim() for example the way rt2x00 driver does: queue a work or schedule a tasklet to update the beacon data on the device. Are there any plans to fix this? The driver is listed as maintained by Ping-Ke. Yeah, power save is hard and I'm not surprised that there are drivers with broken power save mode support. If there's no fix available we should stop supporting AP mode in the driver. https://wireless.wiki.kernel.org/en/developers/documentation/mac80211/api clearly documents that "For AP mode, it must (...) react to the set_tim() callback or fetch each beacon from mac80211". The driver isn't doing either so no wonder the beacon it is sending isn't getting updated. As I have said above, it seems to me that all that needs to be done here is to queue a work in a set_tim() callback, then call send_beacon_frame() from rtlwifi/core.c from this work. But I don't know the exact device semantics, maybe it needs some other notification that the beacon has changed, too, or even tries to manage the TIM bitmap by itself. It would be a shame to lose the AP mode for such minor thing, though. I would play with this myself, but unfortunately I don't have time to work on this right now. That's where my question to Realtek comes: are there plans to actually fix this? Yes, I am working on this. My only question is "if you are such an expert on the problem, why do you not fix it?" The example in rx200 is not particularly useful, and I have not found any other examples. Hi Larry, I have a draft patch that forks a work to do send_beacon_frame(), whose behavior like Maciej mentioned. I did test on RTL8821AE; it works well. But, it seems already work well even I don't apply this patch, and I'm still digging why. I don't have a rtl8192cu dongle on hand, but I'll try to find one. Maceij, Does this patch fix the problem? Larry
linux-next: manual merge of the keys tree with the integrity tree
Hi all, Today's linux-next merge of the keys tree got a conflict in: certs/system_keyring.c between commit: df73a4001959 ("ima: enable loading of build time generated key on .ima keyring") from the integrity tree and commit: 9536390dcc8c ("certs: Move load_system_certificate_list to a common function") from the keys tree. I fixed it up (I think - see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc certs/system_keyring.c index bb122bf4cc17,0c9a4795e847.. --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@@ -133,85 -133,15 +134,34 @@@ static __init int system_trusted_keyrin */ device_initcall(system_trusted_keyring_init); - static __init int load_cert(const u8 *p, const u8 *end, struct key *keyring) - { - key_ref_t key; - size_t plen; - - while (p < end) { - /* Each cert begins with an ASN.1 SEQUENCE tag and must be more -* than 256 bytes in size. -*/ - if (end - p < 4) - goto dodgy_cert; - if (p[0] != 0x30 && - p[1] != 0x82) - goto dodgy_cert; - plen = (p[2] << 8) | p[3]; - plen += 4; - if (plen > end - p) - goto dodgy_cert; - - key = key_create_or_update(make_key_ref(keyring, 1), - "asymmetric", - NULL, - p, - plen, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ), - KEY_ALLOC_NOT_IN_QUOTA | - KEY_ALLOC_BUILT_IN | - KEY_ALLOC_BYPASS_RESTRICTION); - if (IS_ERR(key)) { - pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", - PTR_ERR(key)); - } else { - pr_notice("Loaded X.509 cert '%s'\n", - key_ref_to_ptr(key)->description); - key_ref_put(key); - } - p += plen; - } - - return 0; - - dodgy_cert: - pr_err("Problem parsing in-kernel X.509 certificate list\n"); - return 0; - } - +__init int load_module_cert(struct key *keyring) +{ - const u8 *p, *end; - + if (!IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG)) + return 0; + + pr_notice("Loading compiled-in module X.509 certificates\n"); + - p = system_certificate_list; - end = p + module_cert_size; - - return load_cert(p, end, keyring); ++ return load_certificate_list(system_certificate_list, module_cert_size, ++ keyring); +} + /* * Load the compiled-in list of X.509 certificates. */ static __init int load_system_certificate_list(void) { - const u8 *p, *end; ++ const u8 *p; + pr_notice("Loading compiled-in X.509 certificates\n"); - return load_certificate_list(system_certificate_list, system_certificate_list_size, +#ifdef CONFIG_MODULE_SIG + p = system_certificate_list; +#else + p = system_certificate_list + module_cert_size; +#endif + - end = p + system_certificate_list_size; - return load_cert(p, end, builtin_trusted_keys); ++ return load_certificate_list(p, system_certificate_list_size, +builtin_trusted_keys); } late_initcall(load_system_certificate_list); pgp_23bwCbZhF.pgp Description: OpenPGP digital signature
[PATCH v4] binder: tell userspace to dump current backtrace when detecting oneway spamming
When async binder buffer got exhausted, some normal oneway transactions will also be discarded and may cause system or application failures. By that time, the binder debug information we dump may not be relevant to the root cause. And this issue is difficult to debug if without the backtrace of the thread sending spam. This change will send BR_ONEWAY_SPAM_SUSPECT to userspace when oneway spamming is detected, request to dump current backtrace. Oneway spamming will be reported only once when exceeding the threshold (target process dips below 80% of its oneway space, and current process is responsible for either more than 50 transactions, or more than 50% of the oneway space). And the detection will restart when the async buffer has returned to a healthy state. Signed-off-by: Hang Lu --- v4: add placeholder for BR_FROZEN_REPLY in binder_return_strings for not triggering BUG_ON in print_binder_stats v3: add BR_ONEWAY_SPAM_SUSPECT to binder_return_strings v2: make the detection on/off switch to be per-proc drivers/android/binder.c| 31 +++ drivers/android/binder_alloc.c | 15 --- drivers/android/binder_alloc.h | 8 +++- drivers/android/binder_internal.h | 6 +- include/uapi/linux/android/binder.h | 8 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index c119736..7046af90 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3007,7 +3007,10 @@ static void binder_transaction(struct binder_proc *proc, goto err_bad_object_type; } } - tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; + if (t->buffer->oneway_spam_suspect) + tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; + else + tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; t->work.type = BINDER_WORK_TRANSACTION; if (reply) { @@ -3875,9 +3878,14 @@ static int binder_thread_read(struct binder_proc *proc, binder_stat_br(proc, thread, cmd); } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { + case BINDER_WORK_TRANSACTION_COMPLETE: + case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT: { + if (proc->oneway_spam_detection_enabled && + w->type == BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT) + cmd = BR_ONEWAY_SPAM_SUSPECT; + else + cmd = BR_TRANSACTION_COMPLETE; binder_inner_proc_unlock(proc); - cmd = BR_TRANSACTION_COMPLETE; kfree(w); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); if (put_user(cmd, (uint32_t __user *)ptr)) @@ -4727,6 +4735,18 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; } + case BINDER_ENABLE_ONEWAY_SPAM_DETECTION: { + uint32_t enable; + + if (copy_from_user(, ubuf, sizeof(enable))) { + ret = -EINVAL; + goto err; + } + binder_inner_proc_lock(proc); + proc->oneway_spam_detection_enabled = (bool)enable; + binder_inner_proc_unlock(proc); + break; + } default: ret = -EINVAL; goto err; @@ -5385,7 +5405,10 @@ static const char * const binder_return_strings[] = { "BR_FINISHED", "BR_DEAD_BINDER", "BR_CLEAR_DEATH_NOTIFICATION_DONE", - "BR_FAILED_REPLY" + "BR_FAILED_REPLY", + /* set placeholder for BR_FROZEN_REPLY */ + "PLACEHOLDER", + "BR_ONEWAY_SPAM_SUSPECT" }; static const char * const binder_command_strings[] = { diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 7caf74a..340515f 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -338,7 +338,7 @@ static inline struct vm_area_struct *binder_alloc_get_vma( return vma; } -static void debug_low_async_space_locked(struct binder_alloc *alloc, int pid) +static bool debug_low_async_space_locked(struct binder_alloc *alloc, int pid) { /* * Find the amount and size of buffers allocated by the current caller; @@ -366,13 +366,19 @@ static void debug_low_async_space_locked(struct binder_alloc *alloc, int pid) /* * Warn if this pid has more than 50 transactions, or more than 50% of -* async space (which is 25% of total buffer size). +* async space (which is 25% of total buffer size). Oneway spam is only +* detected when the threshold is exceeded. */ if (num_buffers > 50 ||
[PATCH] Input: cyapa - Fix rumtime PM imbalance on error
When mutex_lock_interruptible() fails, a pairing PM usage counter decrement is needed to keep the counter balanced. Signed-off-by: Dinghao Liu --- drivers/input/mouse/cyapa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index 77cc653edca2..e411ab45a218 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -904,8 +904,10 @@ static ssize_t cyapa_update_rt_suspend_scanrate(struct device *dev, pm_runtime_get_sync(dev); error = mutex_lock_interruptible(>state_sync_lock); - if (error) + if (error) { + pm_runtime_put_noidle(dev); return error; + } cyapa->runtime_suspend_sleep_time = min_t(u16, time, 1000); cyapa->runtime_suspend_power_mode = -- 2.17.1
[PATCH] staging: rtl8192e: rtl8192E_dev: remove unused variable
Fix the following gcc warning: drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c:693:15: warning: variable ‘tmpRegC’ set but not used [-Wunused-but-set-variable]. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index ff843d7..8dbb31f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -690,7 +690,7 @@ bool rtl92e_start_adapter(struct net_device *dev) u8 tmpvalue; u8 ICVersion, SwitchingRegulatorOutput; bool bfirmwareok = true; - u32 tmpRegA, tmpRegC, TempCCk; + u32 tmpRegA, TempCCk; int i = 0; u32 retry_times = 0; @@ -889,8 +889,8 @@ bool rtl92e_start_adapter(struct net_device *dev) if (priv->IC_Cut >= IC_VersionCut_D) { tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); - tmpRegC = rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, - bMaskDWord); + rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord); + for (i = 0; i < TxBBGainTableLength; i++) { if (tmpRegA == dm_tx_bb_gain[i]) { priv->rfa_txpowertrackingindex = (u8)i; -- 1.8.3.1
Re: [PATCH][next] erofs: fix uninitialized variable i used in a while-loop
Hi Joe, On Tue, Apr 06, 2021 at 08:38:44PM -0700, Joe Perches wrote: > On Wed, 2021-04-07 at 07:54 +0800, Gao Xiang wrote: > > Hi Colin, > > > > On Tue, Apr 06, 2021 at 05:27:18PM +0100, Colin King wrote: > > > From: Colin Ian King > > > > > > The while-loop iterates until src is non-null or i is 3, however, the > > > loop counter i is not intinitialied to zero, causing incorrect iteration > > > counts. Fix this by initializing it to zero. > > > > > > Addresses-Coverity: ("Uninitialized scalar variable") > > > Fixes: 1aa5f2e2feed ("erofs: support decompress big pcluster for lz4 > > > backend") > > > Signed-off-by: Colin Ian King > > > > Thank you very much for catching this! It looks good to me, > > Reviewed-by: Gao Xiang > > > > (btw, may I fold this into the original patchset? since such big pcluster > > patchset is just applied to for-next for further integration testing, and > > the commit id is not stable yet..) > > > > Thanks, > > Gao Xiang > > I think this code is odd and would be more intelligible using > a for loop like: Thanks for your reply/suggestion. > --- > fs/erofs/decompressor.c | 20 > 1 file changed, 8 insertions(+), 12 deletions(-) > > diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c > index 27aa6a99b371..5a64f4649414 100644 > --- a/fs/erofs/decompressor.c > +++ b/fs/erofs/decompressor.c > @@ -286,28 +286,24 @@ static int z_erofs_decompress_generic(struct > z_erofs_decompress_req *rq, > } > > ret = alg->prepare_destpages(rq, pagepool); > - if (ret < 0) { > + if (ret < 0) > return ret; > - } else if (ret) { > + if (ret) { > dst = page_address(*rq->out); > dst_maptype = 1; > goto dstmap_out; > } I agree with the modification here, thanks! > > - i = 0; > - while (1) { > + for (i = 0; i < 3; i++) { > dst = vm_map_ram(rq->out, nrpages_out, -1); > - > + if (dst) { > + dst_maptype = 2; > + goto dstmap_out; > + } > /* retry two more times (totally 3 times) */ > - if (dst || ++i >= 3) > - break; > vm_unmap_aliases(); That is not quite equivalent, since after trying more than 3 times, (I think) no need to do the final vm_unmap_aliases(), since it's only used for the next vm_map_ram(). Similar logic also see: fs/xfs/xfs_buf.c: _xfs_buf_map_pages(): /* * vm_map_ram() will allocate auxiliary structures (e.g. * pagetables) with GFP_KERNEL, yet we are likely to be under * GFP_NOFS context here. Hence we need to tell memory reclaim * that we are in such a context via PF_MEMALLOC_NOFS to prevent * memory reclaim re-entering the filesystem here and * potentially deadlocking. */ nofs_flag = memalloc_nofs_save(); do { bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, -1); if (bp->b_addr) break; vm_unmap_aliases(); } while (retried++ <= 1); memalloc_nofs_restore(nofs_flag); if (!bp->b_addr) return -ENOMEM; but yeah with some modification (and extra vm_unmap_aliases() here as well...) Thanks, Gao Xiang
[PATCH v3 4/4] ima: add support for rsa pss verification
This patch adds support for ima verification for rsa with pss encoding. And a patch for ima-evm-utils will be sent later. Signed-off-by: Hongbo Li --- security/integrity/digsig_asymmetric.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 23240d7..ef7a51a 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -85,6 +85,7 @@ int asymmetric_verify(struct key *keyring, const char *sig, struct public_key_signature pks; struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig; const struct public_key *pk; + struct public_key_signature *cert_sig; struct key *key; int ret; @@ -109,16 +110,21 @@ int asymmetric_verify(struct key *keyring, const char *sig, pk = asymmetric_key_public_key(key); pks.pkey_algo = pk->pkey_algo; - if (!strcmp(pk->pkey_algo, "rsa")) - pks.encoding = "pkcs1"; - else if (!strncmp(pk->pkey_algo, "ecdsa-", 6)) + if (!strcmp(pk->pkey_algo, "rsa")) { + cert_sig = key->payload.data[asym_auth]; + if (cert_sig) + pks.encoding = cert_sig->encoding; + else + pks.encoding = "pkcs1"; + } else if (!strncmp(pk->pkey_algo, "ecdsa-", 6)) { /* edcsa-nist-p192 etc. */ pks.encoding = "x962"; - else if (!strcmp(pk->pkey_algo, "ecrdsa") || - !strcmp(pk->pkey_algo, "sm2")) + } else if (!strcmp(pk->pkey_algo, "ecrdsa") || + !strcmp(pk->pkey_algo, "sm2")) { pks.encoding = "raw"; - else + } else { return -ENOPKG; + } pks.digest = (u8 *)data; pks.digest_size = datalen; -- 1.8.3.1
[PATCH v3 3/4] crypto: add rsa pss test vector
This patch adds the test vector for rsa with pss encoding. Signed-off-by: Hongbo Li --- crypto/testmgr.c | 7 + crypto/testmgr.h | 90 2 files changed, 97 insertions(+) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 10c5b3b..2b07fdb 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -5216,6 +5216,13 @@ static int alg_test_null(const struct alg_test_desc *desc, .test = alg_test_null, .fips_allowed = 1, }, { + .alg = "psspad(rsa)", + .test = alg_test_akcipher, + .fips_allowed = 1, + .suite = { + .akcipher = __VECS(psspad_rsa_tv_template) + } + }, { .alg = "poly1305", .test = alg_test_hash, .suite = { diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 34e4a3d..0402db5 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -1239,6 +1239,96 @@ struct kpp_testvec { } }; +/* + * RSA PSS test vectors. Obtained from 186-3rsatestvectors.zip + */ +static const struct akcipher_testvec psspad_rsa_tv_template[] = { + { + .key = + /* Sequence of n , e */ + "\x30\x82\x02\x09" + /* n */ + "\x02\x82\x01\x01\x00" + "\xc5\x06\x2b\x58\xd8\x53\x9c\x76\x5e\x1e\x5d\xba\xf1\x4c\xf7\x5d" + "\xd5\x6c\x2e\x13\x10\x5f\xec\xfd\x1a\x93\x0b\xbb\x59\x48\xff\x32" + "\x8f\x12\x6a\xbe\x77\x93\x59\xca\x59\xbc\xa7\x52\xc3\x08\xd2\x81" + "\x57\x3b\xc6\x17\x8b\x6c\x0f\xef\x7d\xc4\x45\xe4\xf8\x26\x43\x04" + "\x37\xb9\xf9\xd7\x90\x58\x1d\xe5\x74\x9c\x2c\xb9\xcb\x26\xd4\x2b" + "\x2f\xee\x15\xb6\xb2\x6f\x09\xc9\x96\x70\x33\x64\x23\xb8\x6b\xc5" + "\xbe\xc7\x11\x13\x15\x7b\xe2\xd9\x44\xd7\xff\x3e\xeb\xff\xb2\x84" + "\x13\x14\x3e\xa3\x67\x55\xdb\x0a\xe6\x2f\xf5\xb7\x24\xee\xcb\x3d" + "\x31\x6b\x6b\xac\x67\xe8\x9c\xac\xd8\x17\x19\x37\xe2\xab\x19\xbd" + "\x35\x3a\x89\xac\xea\x8c\x36\xf8\x1c\x89\xa6\x20\xd5\xfd\x2e\xff" + "\xea\x89\x66\x01\xc7\xf9\xda\xca\x7f\x03\x3f\x63\x5a\x3a\x94\x33" + "\x31\xd1\xb1\xb4\xf5\x28\x87\x90\xb5\x3a\xf3\x52\xf1\x12\x1c\xa1" + "\xbe\xf2\x05\xf4\x0d\xc0\x12\xc4\x12\xb4\x0b\xdd\x27\x58\x5b\x94" + "\x64\x66\xd7\x5f\x7e\xe0\xa7\xf9\xd5\x49\xb4\xbe\xce\x6f\x43\xac" + "\x3e\xe6\x5f\xe7\xfd\x37\x12\x33\x59\xd9\xf1\xa8\x50\xad\x45\x0a" + "\xaf\x5c\x94\xeb\x11\xde\xa3\xfc\x0f\xc6\xe9\x85\x6b\x18\x05\xef" + /* e */ + "\x02\x82\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xc9\x4f", + .key_len = 525, + .params = + "\x30\x30" + "\xa0\x0d\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\xa1" + "\x1a\x30\x18\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x08\x30\x0b" + "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\xa2\x03\x02\x01\x20", + .param_len = 50, + /* +* m is SHA256 hash of following message: +* "\xdf\xc2\x26\x04\xb9\x5d\x15\x32\x80\x59\x74\x5c\x6c\x98\xeb" +* "\x9d\xfb\x34\x7c\xf9\xf1\x70\xaf\xf1\x9d\xee\xec\x55\x5f\x22" +* "\x28\x5a\x67\x06\xc4\xec\xbf\x0f\xb1\x45\x8c\x60\xd9\xbf\x91" +* "\x3f\xba\xe6\xf4\xc5\x54\xd2\x45\xd9\x46\xb4\xbc\x5f\x34\xae" +* "\xc2\xac\x6b\xe8\xb3\x3d\xc8\xe0\xe3\xa9\xd6\x01\xdf\xd5\x36" +* "\x78\xf5\x67\x44\x43\xf6\x7d\xf7\x8a\x3a\x9e\x09\x33\xe5\xf1" +* "\x58\xb1\x69\xac\x8d\x1c\x4c\xd0\xfb\x87\x2c\x14\xca\x8e\x00" +* "\x1e\x54\x2e\xa0\xf9\xcf\xda\x88\xc4\x2d\xca\xd8\xa7\x40\x97" +* "\xa0\x0c\x22\x05\x5b\x0b\xd4\x1f" +*/ + .m = + "\xb9\x8a\x0d\x22\xe8\x37\xb1\x01\x87\x4a\x5f\x0d\x7a\xd4\x98\x36" + "\xe6\x27\x3f\xc7\x5c\xd2\xd0\x73\xdc\x81\xd9\x6f\x05\xf5\x8f\x3c", + .m_size = 32, + .c = +
[PATCH v3 2/4] crypto: support rsa-pss encoding
This patch add the support of rsa-pss encoding which is described rfc8017. Similar to rsa-pkcs1, we create a pss template. Signed-off-by: Hongbo Li --- crypto/Makefile | 7 +- crypto/rsa-psspad.c | 398 ++ crypto/rsa.c | 14 +- crypto/rsa_helper.c | 127 ++ crypto/rsapss_params.asn1 | 21 +++ include/crypto/internal/rsa.h | 25 ++- 6 files changed, 583 insertions(+), 9 deletions(-) create mode 100644 crypto/rsa-psspad.c create mode 100644 crypto/rsapss_params.asn1 diff --git a/crypto/Makefile b/crypto/Makefile index 10526d4..2c65744 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -33,13 +33,18 @@ obj-$(CONFIG_CRYPTO_DH) += dh_generic.o $(obj)/rsapubkey.asn1.o: $(obj)/rsapubkey.asn1.c $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.o: $(obj)/rsaprivkey.asn1.c $(obj)/rsaprivkey.asn1.h -$(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.h +$(obj)/rsapss_params.asn1.o: $(obj)/rsapss_params.asn1.c \ +$(obj)/rsapss_params.asn1.h +$(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.h \ +$(obj)/rsapss_params.asn1.h rsa_generic-y := rsapubkey.asn1.o rsa_generic-y += rsaprivkey.asn1.o +rsa_generic-y += rsapss_params.asn1.o rsa_generic-y += rsa.o rsa_generic-y += rsa_helper.o rsa_generic-y += rsa-pkcs1pad.o +rsa_generic-y += rsa-psspad.o obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o $(obj)/sm2signature.asn1.o: $(obj)/sm2signature.asn1.c $(obj)/sm2signature.asn1.h diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c new file mode 100644 index 000..cf4d69f --- /dev/null +++ b/crypto/rsa-psspad.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * RSA PSS padding templates. + * + * Copyright (c) 2021 Hongbo Li + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include + +struct psspad_inst_ctx { + struct crypto_akcipher_spawn spawn; +}; + +struct psspad_request { + struct scatterlist out_sg[1]; + uint8_t *out_buf; + struct akcipher_request child_req; +}; + +static const u8 *psspad_unpack(void *dst, const void *src, size_t sz) +{ + memcpy(dst, src, sz); + return src + sz; +} + +static int psspad_set_pub_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct rsa_pss_ctx *ctx = akcipher_tfm_ctx(tfm); + const u8 *ptr; + u32 algo, paramlen; + int err; + + ctx->key_size = 0; + + err = crypto_akcipher_set_pub_key(ctx->child, key, keylen); + if (err) + return err; + + /* Find out new modulus size from rsa implementation */ + err = crypto_akcipher_maxsize(ctx->child); + if (err > PAGE_SIZE) + return -EOPNOTSUPP; + + ctx->key_size = err; + + ptr = key + keylen; + ptr = psspad_unpack(, ptr, sizeof(algo)); + ptr = psspad_unpack(, ptr, sizeof(paramlen)); + err = rsa_parse_pss_params(ctx, ptr, paramlen); + if (err < 0) + return err; + + if (!ctx->hash_algo) + ctx->hash_algo = "sha1"; + if (!ctx->mgf_algo) + ctx->mgf_algo = "mgf1"; + if (!ctx->mgf_hash_algo) + ctx->mgf_hash_algo = "sha1"; + if (!ctx->salt_len) + ctx->salt_len = RSA_PSS_DEFAULT_SALT_LEN; + + return 0; +} + +static int psspad_mgf1(const char *hash_algo, u8 *seed, u32 seed_len, u8 *mask, + u32 masklen) +{ + struct crypto_shash *tfm = NULL; + u32 hlen, cnt, tlen; + u8 c[4], digest[RSA_MAX_DIGEST_SIZE], buf[RSA_MAX_DIGEST_SIZE + 4]; + int i, err = 0; + SHASH_DESC_ON_STACK(desc, tfm); + + tfm = crypto_alloc_shash(hash_algo, 0, 0); + if (IS_ERR(tfm)) { + err = PTR_ERR(tfm); + return err; + } + desc->tfm = tfm; + hlen = crypto_shash_digestsize(tfm); + cnt = DIV_ROUND_UP(masklen, hlen); + tlen = 0; + for (i = 0; i < cnt; i++) { + /* C = I2OSP (counter, 4) */ + c[0] = (i >> 24) & 0xff; + c[1] = (i >> 16) & 0xff; + c[2] = (i >> 8) & 0xff; + c[3] = i & 0xff; + + memcpy(buf, seed, seed_len); + memcpy(buf + seed_len, c, 4); + err = crypto_shash_digest(desc, buf, + seed_len + 4, digest); + if (err < 0) + goto free; + + /* T = T || Hash(mgfSeed || C) */ + tlen = i * hlen; + if (i == cnt - 1) + memcpy(mask + tlen, digest, masklen -
[PATCH v3 1/4] x509: add support for rsa-pss
This patch make x509 support rsa-pss, because the sha algo is in paramters, so we need to parse the sha parameter, and skip other params. Signed-off-by: Hongbo Li --- crypto/asymmetric_keys/Makefile| 7 ++- crypto/asymmetric_keys/public_key.c| 5 ++ crypto/asymmetric_keys/x509_cert_parser.c | 71 -- crypto/asymmetric_keys/x509_rsapss_params.asn1 | 19 +++ include/linux/oid_registry.h | 2 + 5 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 crypto/asymmetric_keys/x509_rsapss_params.asn1 diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index 28b91ad..9092de7 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -20,15 +20,20 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o x509_key_parser-y := \ x509.asn1.o \ x509_akid.asn1.o \ + x509_rsapss_params.asn1.o \ x509_cert_parser.o \ x509_public_key.o $(obj)/x509_cert_parser.o: \ $(obj)/x509.asn1.h \ - $(obj)/x509_akid.asn1.h + $(obj)/x509_akid.asn1.h \ + $(obj)/x509_rsapss_params.asn1.h + $(obj)/x509.asn1.o: $(obj)/x509.asn1.c $(obj)/x509.asn1.h $(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h +$(obj)/x509_rsapss_params.asn1.o: \ + $(obj)/x509_rsapss_params.asn1.c $(obj)/x509_rsapss_params.asn1.h # # PKCS#8 private key handling diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 4fefb21..8f16d4d 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -84,6 +84,11 @@ int software_key_determine_akcipher(const char *encoding, "pkcs1pad(%s,%s)", pkey->pkey_algo, hash_algo); return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0; + } else if (strcmp(encoding, "pss") == 0) { + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"psspad(%s)", +pkey->pkey_algo); + return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0; } if (strcmp(encoding, "raw") == 0 || diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 6d00309..c2e5437 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -15,6 +15,7 @@ #include "x509_parser.h" #include "x509.asn1.h" #include "x509_akid.asn1.h" +#include "x509_rsapss_params.asn1.h" struct x509_parse_context { struct x509_certificate *cert; /* Certificate being constructed */ @@ -115,6 +116,17 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) cert->pub->paramlen = ctx->params_size; cert->pub->algo = ctx->key_algo; + if (!strcmp(cert->sig->pkey_algo, "rsa") && + !strcmp(cert->sig->encoding, "pss") && + cert->pub->paramlen) { + ret = asn1_ber_decoder(_rsapss_params_decoder, ctx, + cert->pub->params, cert->pub->paramlen); + if (ret < 0) { + pr_warn("Couldn't decode rsapss params\n"); + goto error_decode; + } + } + /* Grab the signature bits */ ret = x509_get_sig_params(cert); if (ret < 0) @@ -211,6 +223,10 @@ int x509_note_pkey_algo(void *context, size_t hdrlen, ctx->cert->sig->hash_algo = "sha1"; goto rsa_pkcs1; + case OID_rsa_pss: + ctx->cert->sig->hash_algo = "sha1"; + goto rsa_pss; + case OID_sha256WithRSAEncryption: ctx->cert->sig->hash_algo = "sha256"; goto rsa_pkcs1; @@ -265,6 +281,11 @@ int x509_note_pkey_algo(void *context, size_t hdrlen, ctx->cert->sig->encoding = "pkcs1"; ctx->algo_oid = ctx->last_oid; return 0; +rsa_pss: + ctx->cert->sig->pkey_algo = "rsa"; + ctx->cert->sig->encoding = "pss"; + ctx->algo_oid = ctx->last_oid; + return 0; ecrdsa: ctx->cert->sig->pkey_algo = "ecrdsa"; ctx->cert->sig->encoding = "raw"; @@ -466,17 +487,59 @@ int x509_note_params(void *context, size_t hdrlen, struct x509_parse_context *ctx = context; /* -* AlgorithmIdentifier is used three times in the x509, we should skip -* first and ignore third, using second one which is after subject and -* before subjectPublicKey. +* AlgorithmIdentifier is used three times in the x509, +* rsapss: +* we skip first(same as third) and second(may omit params). +* others: +* we should skip first and ignore third, using second one +* which is after subject and before subjectPublicKey. */ - if (!ctx->cert->raw_subject ||
Re: [PATCH] net/mlx5: fix kfree mismatch in indir_table.c
On Mon, 2021-04-05 at 07:56 +0300, Leon Romanovsky wrote: > On Mon, Apr 05, 2021 at 10:53:39AM +0800, Xiaoming Ni wrote: > > Memory allocated by kvzalloc() should be freed by kvfree(). > > > > Fixes: 34ca65352ddf2 ("net/mlx5: E-Switch, Indirect table > > infrastructur") > > Signed-off-by: Xiaoming Ni > > --- > > .../net/ethernet/mellanox/mlx5/core/esw/indir_table.c | 10 +- > > > > 1 file changed, 5 insertions(+), 5 deletions(-) > > > > Thanks, > Reviewed-by: Leon Romanovsky Applied to net-mlx5. Thanks, Saeed.
[PATCH v3 0/4] crypto: add rsa pss support for x509
From: Hongbo Li This series of patches adds support for x509 cert signed by RSA with PSS encoding method. RSA PSS is described in rfc8017. Patch1 make x509 support rsa pss encoding and parse hash parameter. Patch2 add rsa pss template. Patch3 add test vector for rsa pss. Patch4 is the rsa-pss's ima patch. Test by the following script, it tests different saltlen, hash, mgfhash. keyctl newring test @u while :; do for modbits in 1024 2048 4096; do if [ $modbits -eq 1024 ]; then saltlen=(-1 -2 0 20 32 48 64 94) elif [ $modbits -eq 2048 ]; then saltlen=(-1 -2 0 20 32 48 64 222) else saltlen=(-1 -2 0 20 32 48 64 478) fi for slen in ${saltlen[@]}; do for hash in sha1 sha224 sha256 sha384 sha512; do for mgfhash in sha1 sha224 sha256 sha384 sha512; do certfile="cert.der" echo slen $slen openssl req \ -x509 \ -${hash} \ -newkey rsa:$modbits \ -keyout key.pem \ -days 365 \ -subj '/CN=test' \ -nodes \ -sigopt rsa_padding_mode:pss \ -sigopt rsa_mgf1_md:$mgfhash \ -sigopt rsa_pss_saltlen:${slen} \ -outform der \ -out ${certfile} 2>/dev/null exp=0 id=$(keyctl padd asymmetric testkey %keyring:test < "${certfile}") rc=$? if [ $rc -ne $exp ]; then case "$exp" in 0) echo "Error: Could not load rsa-pss certificate!";; esac echo "modbits $modbits sha: $hash mgfhash $mgfhash saltlen: $slen" exit 1 else case "$rc" in 0) echo "load cert: keyid: $id modbits $modbits hash: $hash mgfhash $mgfhash saltlen $slen" esac fi done done done done done Best Regards Hongbo v2-v3: -add the crypto/rsa-psspad.c which is missed in previous patch v1->v2: -rebase patches to cryptodev/master to fix the issues that reported-by: kernel test robot Hongbo Li (4): x509: add support for rsa-pss crypto: support rsa-pss encoding crypto: add rsa pss test vector ima: add support for rsa pss verification crypto/Makefile| 7 +- crypto/asymmetric_keys/Makefile| 7 +- crypto/asymmetric_keys/public_key.c| 5 + crypto/asymmetric_keys/x509_cert_parser.c | 71 - crypto/asymmetric_keys/x509_rsapss_params.asn1 | 19 ++ crypto/rsa-psspad.c| 398 + crypto/rsa.c | 14 +- crypto/rsa_helper.c| 127 crypto/testmgr.c | 7 + crypto/testmgr.h | 90 ++ include/crypto/internal/rsa.h | 25 +- include/linux/oid_registry.h | 2 + security/integrity/digsig_asymmetric.c | 18 +- 13 files changed, 770 insertions(+), 20 deletions(-) create mode 100644 crypto/asymmetric_keys/x509_rsapss_params.asn1 create mode 100644 crypto/rsa-psspad.c -- 1.8.3.1
[PATCH] iio: light: gp2ap002: Fix rumtime PM imbalance on error
When devm_request_threaded_irq() fails, we should decrease the runtime PM counter to keep the counter balanced. But when iio_device_register() fails, we need not to decrease it because we have already decreased it before. Signed-off-by: Dinghao Liu --- drivers/iio/light/gp2ap002.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index 7ba7aa59437c..040d8429a6e0 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -583,7 +583,7 @@ static int gp2ap002_probe(struct i2c_client *client, "gp2ap002", indio_dev); if (ret) { dev_err(dev, "unable to request IRQ\n"); - goto out_disable_vio; + goto out_put_pm; } gp2ap002->irq = client->irq; @@ -613,8 +613,9 @@ static int gp2ap002_probe(struct i2c_client *client, return 0; -out_disable_pm: +out_put_pm: pm_runtime_put_noidle(dev); +out_disable_pm: pm_runtime_disable(dev); out_disable_vio: regulator_disable(gp2ap002->vio); -- 2.17.1
[PATCH v1] drm/radeon: Fix a missing check bug in radeon_dp_mst_detect()
From: Yingjie Wang In radeon_dp_mst_detect(), We should check whether or not @connector has been unregistered from userspace. If the connector is unregistered, we should return disconnected status. Fixes: 9843ead08f18 ("drm/radeon: add DisplayPort MST support (v2)") Signed-off-by: Yingjie Wang --- drivers/gpu/drm/radeon/radeon_dp_mst.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 2c32186c4acd..4e4c937c36c6 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -242,6 +242,9 @@ radeon_dp_mst_detect(struct drm_connector *connector, to_radeon_connector(connector); struct radeon_connector *master = radeon_connector->mst_port; + if (drm_connector_is_unregistered(connector)) + return connector_status_disconnected; + return drm_dp_mst_detect_port(connector, ctx, >mst_mgr, radeon_connector->port); } -- 2.7.4
[PATCH] lib: parser: clean up kernel-doc
Mark match_uint() as kernel-doc notation since it is already fully annotated as such. Use % prefix on constants in kernel-doc comments. Convert function return descriptions to use the "Return:" kernel-doc notation. Signed-off-by: Randy Dunlap Cc: Andrew Morton Cc: Alexander Viro Cc: David Howells Cc: linux-fsde...@vger.kernel.org --- lib/parser.c | 61 ++--- 1 file changed, 38 insertions(+), 23 deletions(-) --- linux-next-20210406.orig/lib/parser.c +++ linux-next-20210406/lib/parser.c @@ -98,7 +98,7 @@ static int match_one(char *s, const char * locations. * * Description: Detects which if any of a set of token strings has been passed - * to it. Tokens can include up to MAX_OPT_ARGS instances of basic c-style + * to it. Tokens can include up to %MAX_OPT_ARGS instances of basic c-style * format identifiers which will be taken into account when matching the * tokens, and whose locations will be returned in the @args array. */ @@ -120,8 +120,10 @@ EXPORT_SYMBOL(match_token); * @base: base to use when converting string * * Description: Given a _t and a base, attempts to parse the substring - * as a number in that base. On success, sets @result to the integer represented - * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + * as a number in that base. + * + * Return: On success, sets @result to the integer represented by the + * string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. */ static int match_number(substring_t *s, int *result, int base) { @@ -153,8 +155,10 @@ static int match_number(substring_t *s, * @base: base to use when converting string * * Description: Given a _t and a base, attempts to parse the substring - * as a number in that base. On success, sets @result to the integer represented - * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + * as a number in that base. + * + * Return: On success, sets @result to the integer represented by the + * string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. */ static int match_u64int(substring_t *s, u64 *result, int base) { @@ -178,9 +182,10 @@ static int match_u64int(substring_t *s, * @s: substring_t to be scanned * @result: resulting integer on success * - * Description: Attempts to parse the _t @s as a decimal integer. On - * success, sets @result to the integer represented by the string and returns 0. - * Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + * Description: Attempts to parse the _t @s as a decimal integer. + * + * Return: On success, sets @result to the integer represented by the string + * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. */ int match_int(substring_t *s, int *result) { @@ -188,14 +193,15 @@ int match_int(substring_t *s, int *resul } EXPORT_SYMBOL(match_int); -/* +/** * match_uint - scan a decimal representation of an integer from a substring_t * @s: substring_t to be scanned * @result: resulting integer on success * - * Description: Attempts to parse the _t @s as a decimal integer. On - * success, sets @result to the integer represented by the string and returns 0. - * Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + * Description: Attempts to parse the _t @s as a decimal integer. + * + * Return: On success, sets @result to the integer represented by the string + * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. */ int match_uint(substring_t *s, unsigned int *result) { @@ -217,9 +223,10 @@ EXPORT_SYMBOL(match_uint); * @result: resulting unsigned long long on success * * Description: Attempts to parse the _t @s as a long decimal - * integer. On success, sets @result to the integer represented by the - * string and returns 0. - * Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + * integer. + * + * Return: On success, sets @result to the integer represented by the string + * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. */ int match_u64(substring_t *s, u64 *result) { @@ -232,9 +239,10 @@ EXPORT_SYMBOL(match_u64); * @s: substring_t to be scanned * @result: resulting integer on success * - * Description: Attempts to parse the _t @s as an octal integer. On - * success, sets @result to the integer represented by the string and returns - * 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + * Description: Attempts to parse the _t @s as an octal integer. + * + * Return: On success, sets @result to the integer represented by the string + * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. */ int match_octal(substring_t *s, int *result) { @@ -248,8 +256,9 @@ EXPORT_SYMBOL(match_octal); * @result: resulting integer on success * * Description: Attempts to parse the _t @s as a hexadecimal integer. - * On success, sets @result to the integer represented by the string and - * returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE
[PATCH v1 1/2] driver core: Add dev_set_drv_sync_state()
This can be used by frameworks to set the sync_state() helper functions for drivers that don't already have them set. Signed-off-by: Saravana Kannan --- include/linux/device.h | 12 1 file changed, 12 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index ba660731bd25..35e8833ca16b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -778,6 +778,18 @@ static inline bool dev_has_sync_state(struct device *dev) return false; } +static inline int dev_set_drv_sync_state(struct device *dev, +void (*fn)(struct device *dev)) +{ + if (!dev || !dev->driver) + return 0; + if (dev->driver->sync_state && dev->driver->sync_state != fn) + return -EBUSY; + if (!dev->driver->sync_state) + dev->driver->sync_state = fn; + return 0; +} + /* * High level routines for use by the bus drivers */ -- 2.31.1.295.g9ea45b61b8-goog
[PATCH v1 2/2] clk: Add support for sync_state()
Clocks can be turned on (by the hardware, bootloader, etc) upon a reset/boot of a hardware platform. These "boot clocks" could be clocking devices that are active before the kernel starts running. For example, clocks needed for the interconnects, UART console, display, CPUs, DDR, etc. When a boot clock is used by more than one consumer or multiple boot clocks share a parent clock, the boot clock (or the common parent) can be turned off when the first consumer probes. This can crash the device or cause poor user experience. Fix this by explicitly enabling the boot clocks during clock registration and then removing the enable vote when the clock provider device gets its sync_state() callback. Since sync_state() callback comes only when all the consumers of a device (not a specific clock) have probed, this ensures the boot clocks are kept on at least until all their consumers have had a chance to vote on them (in their respective probe functions). Also, if a clock provider is loaded as a module and it has some boot clocks, they get turned off only when a consumer explicitly turns them off. So clocks that are boot clocks and are unused never get turned off because the logic to turn off unused clocks has already run during late_initcall_sync(). Adding sync_state() support also makes sure these unused boot clocks are turned off once all the consumers have probed. Signed-off-by: Saravana Kannan --- drivers/clk/clk.c| 84 +++- include/linux/clk-provider.h | 1 + 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d6301a3351f2..cd07f4d1254c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -72,6 +72,8 @@ struct clk_core { unsigned long flags; boolorphan; boolrpm_enabled; + boolneed_sync; + boolboot_enabled; unsigned intenable_count; unsigned intprepare_count; unsigned intprotect_count; @@ -1215,6 +1217,15 @@ static void __init clk_unprepare_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, >children, child_node) clk_unprepare_unused_subtree(child); + /* +* Orphan clocks might still not have their state held if one of their +* ancestors hasn't been registered yet. We don't want to turn off +* these orphan clocks now as they will be turned off later when their +* device gets a sync_state() call. +*/ + if (dev_has_sync_state(core->dev)) + return; + if (core->prepare_count) return; @@ -1246,6 +1257,15 @@ static void __init clk_disable_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, >children, child_node) clk_disable_unused_subtree(child); + /* +* Orphan clocks might still not have their state held if one of their +* ancestors hasn't been registered yet. We don't want to turn off +* these orphan clocks now as they will be turned off later when their +* device gets a sync_state() call. +*/ + if (dev_has_sync_state(core->dev)) + return; + if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_prepare_enable(core->parent); @@ -1319,6 +1339,38 @@ static int __init clk_disable_unused(void) } late_initcall_sync(clk_disable_unused); +static void clk_unprepare_disable_dev_subtree(struct clk_core *core, + struct device *dev) +{ + struct clk_core *child; + + lockdep_assert_held(_lock); + + hlist_for_each_entry(child, >children, child_node) + clk_unprepare_disable_dev_subtree(child, dev); + + if (core->dev != dev || !core->need_sync) + return; + + clk_core_disable_unprepare(core); +} + +void clk_sync_state(struct device *dev) +{ + struct clk_core *core; + + clk_prepare_lock(); + + hlist_for_each_entry(core, _root_list, child_node) + clk_unprepare_disable_dev_subtree(core, dev); + + hlist_for_each_entry(core, _orphan_list, child_node) + clk_unprepare_disable_dev_subtree(core, dev); + + clk_prepare_unlock(); +} +EXPORT_SYMBOL_GPL(clk_sync_state); + static int clk_core_determine_round_nolock(struct clk_core *core, struct clk_rate_request *req) { @@ -1725,6 +1777,30 @@ int clk_hw_get_parent_index(struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_get_parent_index); +static void clk_core_hold_state(struct clk_core *core) +{ + if (core->need_sync || !core->boot_enabled) + return; + + if (core->orphan || !dev_has_sync_state(core->dev)) + return; + + core->need_sync = !clk_core_prepare_enable(core); +} + +static void
[PATCH v1 0/2] Add sync_state() support to clock framework
Stephen, We can decide later if both these patches land through clk tree or the driver-core tree. The meat of the series is in Patch 2/2 and that commit text gives all the details. Saravana Kannan (2): driver core: Add dev_set_drv_sync_state() clk: Add support for sync_state() drivers/clk/clk.c| 84 +++- include/linux/clk-provider.h | 1 + include/linux/device.h | 12 ++ 3 files changed, 96 insertions(+), 1 deletion(-) -- 2.31.1.295.g9ea45b61b8-goog
RE: [PATCH v6] soc: fsl: enable acpi support in RCPM driver
> -Original Message- > From: Ran Wang > Sent: Tuesday, April 6, 2021 8:32 PM > To: Leo Li > Cc: Christophe Leroy ; linuxppc-dev > ; moderated list:ARM/FREESCALE IMX / MXC > ARM ARCHITECTURE ; lkml ker...@vger.kernel.org> > Subject: RE: [PATCH v6] soc: fsl: enable acpi support in RCPM driver > > Hi Leo, > > On Wednesday, April 7, 2021 5:45 AM, Li Yang wrote: > > > > On Fri, Mar 12, 2021 at 2:56 AM Ran Wang wrote: > > > > > > From: Peng Ma > > > > > > This patch enables ACPI support in RCPM driver. > > > > > > Signed-off-by: Peng Ma > > > Signed-off-by: Ran Wang > > > --- > > > Change in v6: > > > - Remove copyright udpate to rebase on latest mainline > > > > > > Change in v5: > > > - Fix panic when dev->of_node is null > > > > > > Change in v4: > > > - Make commit subject more accurate > > > - Remove unrelated new blank line > > > > > > Change in v3: > > > - Add #ifdef CONFIG_ACPI for acpi_device_id > > > - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids > > > > > > Change in v2: > > > - Update acpi_device_id to fix conflict with other driver > > > > > > drivers/soc/fsl/rcpm.c | 18 -- > > > 1 file changed, 16 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > > > 4ace28cab314..7aa997b932d1 100644 > > > --- a/drivers/soc/fsl/rcpm.c > > > +++ b/drivers/soc/fsl/rcpm.c > > > @@ -13,6 +13,7 @@ > > > #include > > > #include > > > #include > > > +#include > > > > > > #define RCPM_WAKEUP_CELL_MAX_SIZE 7 > > > > > > @@ -78,10 +79,14 @@ static int rcpm_pm_prepare(struct device *dev) > > > "fsl,rcpm-wakeup", value, > > > rcpm->wakeup_cells + 1); > > > > > > - /* Wakeup source should refer to current rcpm device */ > > > - if (ret || (np->phandle != value[0])) > > > + if (ret) > > > continue; > > > > > > + if (is_of_node(dev->fwnode)) > > > + /* Should refer to current rcpm device */ Better to be /* Only handle devices with fsl,rcpm-wakeup pointing to the current rcpm node*/ > > > + if (np->phandle != value[0]) > > > + continue; > > > > It looks like that we assume that in the ACPI scenario there will only > > be one RCPM controller and all devices are controlled by this single > > PM controller. This probably is true for all existing SoCs with a RCPM. > > But > since the driver tried to support multiple RCPMs, maybe we should continue > to support multiple RCPM controllers or at least mention that in the > comment. > > How about adding some comment as below: > > /* For ACPI mode, currently we assume there is only one RCPM controller > existing */ Ok. On the other hand, it will be clearer to update the existing comment above. > > Regards, > Ran > > > > > > + > > > /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines > > > the > > > * number of IPPDEXPCR register cells, and > > > "fsl,rcpm-wakeup" > > > * of wakeup source IP contains an integer array: > > > > > rcpm_of_match[] = { }; MODULE_DEVICE_TABLE(of, rcpm_of_match); > > > > > > +#ifdef CONFIG_ACPI > > > +static const struct acpi_device_id rcpm_acpi_ids[] = { > > > + {"NXP0015",}, > > > + { } > > > +}; > > > +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_ids); #endif > > > + > > > static struct platform_driver rcpm_driver = { > > > .driver = { > > > .name = "rcpm", > > > .of_match_table = rcpm_of_match, > > > + .acpi_match_table = ACPI_PTR(rcpm_acpi_ids), > > > .pm = _pm_ops, > > > }, > > > .probe = rcpm_probe, > > > -- > > > 2.25.1 > > >
Re: [PATCH][next] erofs: fix uninitialized variable i used in a while-loop
On Wed, 2021-04-07 at 07:54 +0800, Gao Xiang wrote: > Hi Colin, > > On Tue, Apr 06, 2021 at 05:27:18PM +0100, Colin King wrote: > > From: Colin Ian King > > > > The while-loop iterates until src is non-null or i is 3, however, the > > loop counter i is not intinitialied to zero, causing incorrect iteration > > counts. Fix this by initializing it to zero. > > > > Addresses-Coverity: ("Uninitialized scalar variable") > > Fixes: 1aa5f2e2feed ("erofs: support decompress big pcluster for lz4 > > backend") > > Signed-off-by: Colin Ian King > > Thank you very much for catching this! It looks good to me, > Reviewed-by: Gao Xiang > > (btw, may I fold this into the original patchset? since such big pcluster > patchset is just applied to for-next for further integration testing, and > the commit id is not stable yet..) > > Thanks, > Gao Xiang I think this code is odd and would be more intelligible using a for loop like: --- fs/erofs/decompressor.c | 20 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 27aa6a99b371..5a64f4649414 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -286,28 +286,24 @@ static int z_erofs_decompress_generic(struct z_erofs_decompress_req *rq, } ret = alg->prepare_destpages(rq, pagepool); - if (ret < 0) { + if (ret < 0) return ret; - } else if (ret) { + if (ret) { dst = page_address(*rq->out); dst_maptype = 1; goto dstmap_out; } - i = 0; - while (1) { + for (i = 0; i < 3; i++) { dst = vm_map_ram(rq->out, nrpages_out, -1); - + if (dst) { + dst_maptype = 2; + goto dstmap_out; + } /* retry two more times (totally 3 times) */ - if (dst || ++i >= 3) - break; vm_unmap_aliases(); } - - if (!dst) - return -ENOMEM; - - dst_maptype = 2; + return -ENOMEM; dstmap_out: ret = alg->decompress(rq, dst + rq->pageofs_out);
[PATCH] vfs: fs_parser: clean up kernel-doc warnings
Fix kernel-doc notation function arguments to eliminate two kernel-doc warnings: fs_parser.c:322: warning: Excess function parameter 'name' description in 'validate_constant_table' fs_parser.c:367: warning: Function parameter or member 'name' not described in 'fs_validate_description' Signed-off-by: Randy Dunlap Cc: Andrew Morton Cc: Alexander Viro Cc: David Howells Cc: linux-fsde...@vger.kernel.org --- fs/fs_parser.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- linux-next-20210406.orig/fs/fs_parser.c +++ linux-next-20210406/fs/fs_parser.c @@ -310,7 +310,6 @@ EXPORT_SYMBOL(fs_param_is_path); #ifdef CONFIG_VALIDATE_FS_PARSER /** * validate_constant_table - Validate a constant table - * @name: Name to use in reporting * @tbl: The constant table to validate. * @tbl_size: The size of the table. * @low: The lowest permissible value. @@ -360,6 +359,7 @@ bool validate_constant_table(const struc /** * fs_validate_description - Validate a parameter description + * @name: The parameter name to search for. * @desc: The parameter description to validate. */ bool fs_validate_description(const char *name,
[PATCH] i2c: omap: Fix rumtime PM imbalance on error
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error. Signed-off-by: Dinghao Liu --- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 12ac4212aded..c9ee0875a79d 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1404,7 +1404,7 @@ omap_i2c_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(omap->dev, OMAP_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(omap->dev); - r = pm_runtime_get_sync(omap->dev); + r = pm_runtime_resume_and_get(omap->dev); if (r < 0) goto err_free_mem; -- 2.17.1