Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S968551AbdIZPyv (ORCPT ); Tue, 26 Sep 2017 11:54:51 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51739 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966056AbdIZPys (ORCPT ); Tue, 26 Sep 2017 11:54:48 -0400 X-AuditID: cbfec7f2-f793b6d000003243-49-59ca7844a184 Subject: Re: [PATCH v2] crypto: s5p-sss: Add HASH support for Exynos To: Krzysztof Kozlowski Cc: linux-crypto@vger.kernel.org, Herbert Xu , Vladimir Zapolskiy , "David S. Miller" , Bartlomiej Zolnierkiewicz , linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org From: Kamil Konieczny Message-id: Date: Tue, 26 Sep 2017 17:54:42 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-version: 1.0 In-reply-to: <20170925182713.ti4esyznyrjr7xh7@kozik-lap> Content-type: text/plain; charset="utf-8" Content-language: en-US Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrBKsWRmVeSWpSXmKPExsWy7djPc7ouFaciDdY8F7TYOGM9q8Wc8y0s Ft2vZCzOn9/AbnH/3k8mi8u75rBZzDi/j8ni/69mZgcOjy0rbzJ5bDug6rFpVSebx7+FU1g8 +rasYvT4vEkugC2KyyYlNSezLLVI3y6BK6Nn9wW2gssOFeuaDjM1MC4z7mLk5JAQMJFo7HrF DGGLSVy4t56ti5GLQ0hgKaPE0r0zWUESQgKfGSV615XDNLw+cIgRomgZo8T651+ZIJxnjBKP 734H6xAWcJHYfbSHDcQWEdCUuP4XJM7FwSwwmUli2/FzYPvYBMwlHm0/wwRi8wq4SVy59gTM ZhFQlejsOMMCYosKREhc2PQTqkZQ4sfke2BxTgELiaa9v8DizEALXnyZxAJhi0s0t96EsuUl Nq95ywyyWELgPpvE/yP32CF+cJE4vWsLI4QtLPHq+BaouIzE5cndLBAN/YwSy2+cYodwpjBK HJ92lQmiylri8PGLrBAr+CQmbZsOtIIDKM4r0dEmBFHiIbFuQg8LhO0osXHqHWiAbWaSuDf3 AOMERvlZSD6aheSLWUi+mIXkiwWMLKsYRVJLi3PTU4uN9YoTc4tL89L1kvNzNzEC08/pf8c/ 7WD8esLqEKMAB6MSD29C7KlIIdbEsuLK3EOMEhzMSiK8X4qBQrwpiZVVqUX58UWlOanFhxil OViUxHlto9oihQTSE0tSs1NTC1KLYLJMHJxSDYxHfyaaCfbPyvzry6BZqhc5v23zrkMrLu9c V5Hhovlwk3uWzN2Fcckv/ll3Kq+e9cp0T+/0Owf+f5ZxtPSWdOyTW9DOz/H1i+fSoj3u22U1 Q7YoyeS37GORTEo50+nnKjnvyhoGVoX2y88UPnTar36m8UuhZVva5NhGndbo+blzizL5nBoz TiixFGckGmoxFxUnAgDhn4ZdOwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrBLMWRmVeSWpSXmKPExsVy+t/xK7rOFaciDX6817TYOGM9q8Wc8y0s Ft2vZCzOn9/AbnH/3k8mi8u75rBZzDi/j8ni/69mZgcOjy0rbzJ5bDug6rFpVSebx7+FU1g8 +rasYvT4vEkugC2KyyYlNSezLLVI3y6BK6Nn9wW2gssOFeuaDjM1MC4z7mLk5JAQMJF4feAQ I4QtJnHh3no2EFtIYAmjxJRvxV2MXED2M0aJLe1/mEASwgIuEruP9oAViQhoSlz/+50VxGYW mMwkcfusL0TDViaJG6+awRJsAuYSj7afAWvmFXCTuHLtCZjNIqAq0dlxhqWLkYNDVCBCYsNG fogSQYkfk++xgNicAhYSTXt/MYGUMAuoS0yZkguxSlyiufUmC4QtL7F5zVvmCYyCs5B0z0Lo mIWkYxaSjgWMLKsYRVJLi3PTc4uN9IoTc4tL89L1kvNzNzEC42PbsZ9bdjB2vQs+xCjAwajE wxsRdipSiDWxrLgy9xCjBAezkgiveixQiDclsbIqtSg/vqg0J7X4EKM0B4uSOG/vntWRQgLp iSWp2ampBalFMFkmDk6pBsbpt3MLeYX27RPpulb/ZpvtuyO2XGdfSut/vWmzuYQ9r+HNske1 slslcxqnHO3bGe+asXH+xin8XqzbExfPWLnvcO4LZwsXc9sjRW3rWhvlXWv3MwVLfOY47/PT LKnCd1li5/3Wd4+0u5iWamqc+K/7dN2k7IV/Q5UF/jPafJ238JMmv/oX7RAlluKMREMt5qLi RAAoknOKiwIAAA== X-CMS-MailID: 20170926155443eucas1p109a92cb48cf162acd950e9d369f3185d X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?S2FtaWwgS29uaWVjem55G1NSUE9MLUtlcm5lbCAoVFApGw==?= =?UTF-8?B?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?S2FtaWwgS29uaWVjem55G1NSUE9MLUtlcm5lbCAoVFApG1Nh?= =?UTF-8?B?bXN1bmcgRWxlY3Ryb25pY3MbU2VuaW9yIFNvZnR3YXJlIEVuZ2luZWVy?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-CMS-RootMailID: 20170915175007eucas1p2912e7a9e1b44e976f96a53d8c8e442ec X-RootMTR: 20170915175007eucas1p2912e7a9e1b44e976f96a53d8c8e442ec References: <20170919190341.5vi5icaxnmynywre@kozik-lap> <8924d30c-6581-28f3-c223-c2a24c491887@partner.samsung.com> <20170925182713.ti4esyznyrjr7xh7@kozik-lap> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8051 Lines: 222 On 25.09.2017 20:27, Krzysztof Kozlowski wrote: > On Fri, Sep 22, 2017 at 08:00:17PM +0200, Kamil Konieczny wrote: >> On 19.09.2017 21:03, Krzysztof Kozlowski wrote: >>> On Fri, Sep 15, 2017 at 07:50:06PM +0200, Kamil Konieczny wrote: > > (...) > >>>> + >>>> +/* HASH flags */ >>> >>> All defines below have "HASH_FLAGS" prefix... so actually useful would >>> be to explain also what is a hash flag. >> >> These are bit numbers used by device driver, setting in dev->hash_flags, >> used with set_bit(), clear_bit() or test_bit(), and with macro BIT(), >> to keep device state BUSY or FREE, or to signal state from irq_handler >> to hash_tasklet. > > Then add something similar as comment to the code. OK. [...] >>>> * @lock: Lock for protecting both access to device hardware registers >>>> - * and fields related to current request (including the busy field). >>>> + * and fields related to current request (including the busy >>>> + * field). >>>> + * @res: Resources for hash. >>>> + * @io_hash_base: Per-variant offset for HASH block IO memory. >>>> + * @hash_lock: Lock for protecting hash_req and other HASH variables. >>> >>> I must admit that I do not see how it protects the hash_req. The >>> hash_req looks untouched (not read, not modified) during this lock >>> critical section. Can you share some more thoughts about it? >> >> It protects dev->hash_queue and dev->hash_flags >> in begin of function s5p_hash_handle_queue. >> >> After dequeue non-null request, bit HASH_BUSY is set in dd->hash_flags, >> and this bit protects dd->hash_req and other fields. From there device >> works with dd->hash_req until finish in irq_handler and hash_tasklet. > > Few thoughts here: > 1. Other accesses to HASH_BUSY bit of hash_flags are not protected with > lock and you are using set_bit/clear_bit which are atomic operations, > so from this perspective it does not protect hash_flags. > 2. This means the only field protected here is hash_queue so I guess you > expect possibility of multiple concurrent calls to s5p_hash_handle_queue(). > This makes sense but then description has to be updated. OK, I will update it. Other bits in dev->hash_flags can be set and cleared only in BUSY state. [...] >>>> + struct tasklet_struct hash_tasklet; >>>> + u8 xmit_buf[BUFLEN] SSS_ALIGNED; >>>> + >>>> + unsigned long hash_flags; >>> >>> This should be probably DECLARE_BITMAP. >> >> I do not get it, it is used for bits HASH_FLAGS_... and is not HW related. >> This will grow this patch even longer. > > Why longer? Only declaration changes, rest should be the same. > Just instead of playing with bits over unsigned long explicitly use a > type for that purpose - DECLARE_BITMAP. It will make code ugly, using &dev->hash_flags[0] instead of &dev->hash_flags. I have 9 bits used, and I will not anticipate it grow above 64. If you insist, I can add DECLARE_BITMAP and rewrite all calls to _bits() functions. [...] >>>> + struct samsung_aes_variant *pdata; >>> >>> This should be const as pdata should not be modified. >> >> You are right, and I do not modify _offsets parts, but only hash >> functions pointers and hash array size. It is made non-const due >> to keeping it in the place, and not moving struct samsung_aes_variant >> below hash functions definitions. >> >> If I need to keep them const, then I will move whole part below, just >> before _probe, so I can properly set hash_algs_info and >> hash_algs_size (and again, small change, but bigger patch). >> >> I can do this, if you think it is safer to have them const. > > I see, you are modifiying the variant->hash_algs_info and > variant->hash_algs_size. However all of them should be static const as > this is not a dynamic data. It does not depend on any runtime > conditions, except of course choosing the variant itself. You are right, I will make samsung_aes_variant const again. [...] >>>> +/** >>>> + * s5p_hash_finish_req - finish request >>>> + * @req: AHASH request >>>> + * @err: error >>>> + * >>>> + * Clear flags, free memory, >>>> + * if FINAL then read output into ctx->digest, >>>> + * call completetion >>>> + */ >>>> +static void s5p_hash_finish_req(struct ahash_request *req, int err) >>>> +{ >>>> + struct s5p_hash_reqctx *ctx = ahash_request_ctx(req); >>>> + struct s5p_aes_dev *dd = ctx->dd; >>>> + >>>> + if (test_bit(HASH_FLAGS_SGS_COPIED, &dd->hash_flags)) >>>> + free_pages((unsigned long)sg_virt(ctx->sg), >>>> + get_order(ctx->sg->length)); >>>> + >>>> + if (test_bit(HASH_FLAGS_SGS_ALLOCED, &dd->hash_flags)) >>>> + kfree(ctx->sg); >>>> + >>>> + ctx->sg = NULL; >>>> + >>>> + dd->hash_flags &= ~(BIT(HASH_FLAGS_SGS_ALLOCED) | >>>> + BIT(HASH_FLAGS_SGS_COPIED)); >>>> + >>>> + if (!err && !test_bit(HASH_FLAGS_ERROR, &ctx->flags)) { >>>> + s5p_hash_read_msg(req); >>>> + if (test_bit(HASH_FLAGS_FINAL, &dd->hash_flags)) >>>> + err = s5p_hash_finish(req); >>>> + } else { >>>> + ctx->flags |= BIT(HASH_FLAGS_ERROR); >>>> + } >>>> + >>>> + /* atomic operation is not needed here */ >>> >>> Ok, but why? >>> >> >> Good question, I frankly copy&paste this. The hash vars in s5p_aes_dev >> are no longer used as all transfers ended, we have req context here >> so after complete we can work on next request, >> and clearing bit HASH_FLAGS_BUSY allows this. > > I think you need them. Here and few lines before. In > s5p_hash_handle_queue() you use spin-lock because it might be executed > multiple times. Having that assumption (multiple calls to > s5p_hash_handle_queue()) you can have: > > Thread #1: Thread #2 > s5p_hash_finish_req() s5p_hash_handle_queue() > dd->hash_flags &= ... > which equals to: somewhere here will be (in Thread #2): if(test_bit(HASH_FLAGS_BUSY,dd->hash_flags)) { unlock, return; } > tmp = dd->hash_flags; > tmp &= ~(BIT...) > set_bit(HASH_FLAGS_BUSY, &dd->hash_flags); > dd->hash_flags = tmp > > Which means that in last assignment you effectively lost the > HASH_FLAGS_BUSY bit. > > In general, you need to use atomics (or locks) everywhere, unless you > are 100% sure that given lockless section cannot be executed with other > code which uses locks. Otherwise the atomics/locks become uneffective. I can add spinlock as I am not 100% sure if below is true: HASH_FLAGS_BUSY is protected by order of instructions and by test_bit. First, this bit is set only in one place, in s5p_hash_handle_queue() and cleared also only in one place, s5p_hash_finish_req(). In function s5p_hash_handle_queue(), after spinlock, bit HASH_FLAGS_BUSY is tested and if set, there is unlock and exit, and the flow reaches next instructions only when this bit was not set. Setting bit is in the same spinlock section, so as you write, concurrent calls to s5p_hash_handle_queue are protected by spinlock. [...] >>>> + */ >>>> +static struct sss_hash_algs_info exynos_hash_algs_info[] = { >>> >>> Can it be const? >>> >> >> They can, but for this I must move aes variant structures and _variant function >> before _probe. > > Ok, move them, maybe in different patch in that case since this is just > re-order and this commit is pretty big already. There are some fields set in this struct before HASH algorithm registration (in _probe()). I will try to avoid aes code moves. [...] >>> Run checkpatch. >>> >> >> Can you write more ? What options I should use ? >> I ran and it gives zero errors, one warn about __attribute__(aligned()), >> and one about Kconfig change (description len too low). > > Oh, my bad, I thought it would complain about comment coding style. > There should be opening /* before any text: > /* > * this is > * long comment > */ > > But anyway you can run it with --strict and fix the minor issues for new > code (like "Alignment should match open parenthesis", "Please use a > blank line after"). These are not critical but for new code they are > welcomed, I think. Thank you, I will add this option to my process. -- Best regards, Kamil Konieczny Samsung R&D Institute Poland