Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Christian Borntraeger @ 2017-03-02 19:00 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney
In-Reply-To: <CAK8P3a082Bi6Vf5gEFLAJtJvUm=7MtddBzcCOqagQyfJPFTu_g@mail.gmail.com>

On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
> <borntraeger@de.ibm.com> wrote:
>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>
>>> This attempts a rewrite of the two macros, using a simpler implementation
>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>> 64-bit architectures) 8  byte object that can be accessed with a single
>>> instruction.  For these, we go back to a volatile pointer dereference
>>> that we had with the ACCESS_ONCE macro.
>>
>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>> removed the volatile statement on aggregate types like the following one
>>
>> union ipte_control {
>>         unsigned long val;
>>         struct {
>>                 unsigned long k  : 1;
>>                 unsigned long kh : 31;
>>                 unsigned long kg : 32;
>>         };
>> };
>>
>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>
>> If I see that right, your __ALIGNED_WORD(x)
>> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
>> so it would fall back to the old volatile cast and might reintroduce the
>> old compiler bug?

Oh dear, I should double check my sentences in emails before sending...anyway
the full story is referenced in 

commit 60815cf2e05057db5b78e398d9734c493560b11e
    Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
which has a pointer to
http://marc.info/?i=54611D86.4040306%40de.ibm.com
which contains the full story.

> 
> Ah, right, that's the missing piece. For some reason I didn't find
> the reference in the source or the git log.
> 
>> Could you maybe you fence your simple macro for anything older than 4.9? After
>> all there was no kasan support anyway on these older gcc version.
> 
> Yes, that should work, thanks!

^ permalink raw reply

* Re: pull-request: mac80211 2017-03-02
From: David Miller @ 2017-03-02 22:39 UTC (permalink / raw)
  To: johannes; +Cc: netdev, linux-wireless
In-Reply-To: <20170302103443.18251-1-johannes@sipsolutions.net>

From: Johannes Berg <johannes@sipsolutions.net>
Date: Thu,  2 Mar 2017 11:34:42 +0100

> As I mentioned in my other pull request, here's the change
> for the average.h to make the precision easier to use.
> 
> Please pull and let me know if there's any problem.

Pulled, thanks Johannes.

^ permalink raw reply

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Christian Borntraeger @ 2017-03-02 16:51 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Paul McKenney
In-Reply-To: <20170302163834.2273519-3-arnd@arndb.de>

On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
> When CONFIG_KASAN is enabled, the READ_ONCE/WRITE_ONCE macros cause
> rather large kernel stacks, e.g.:
> 
> mm/vmscan.c: In function 'shrink_page_list':
> mm/vmscan.c:1333:1: error: the frame size of 3456 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> block/cfq-iosched.c: In function 'cfqg_stats_add_aux':
> block/cfq-iosched.c:750:1: error: the frame size of 4048 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/btrfs/disk-io.c: In function 'open_ctree':
> fs/btrfs/disk-io.c:3314:1: error: the frame size of 3136 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/btrfs/relocation.c: In function 'build_backref_tree':
> fs/btrfs/relocation.c:1193:1: error: the frame size of 4336 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/fscache/stats.c: In function 'fscache_stats_show':
> fs/fscache/stats.c:287:1: error: the frame size of 6512 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> fs/jbd2/commit.c: In function 'jbd2_journal_commit_transaction':
> fs/jbd2/commit.c:1139:1: error: the frame size of 3760 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> 
> This attempts a rewrite of the two macros, using a simpler implementation
> for the most common case of having a naturally aligned 1, 2, 4, or (on
> 64-bit architectures) 8  byte object that can be accessed with a single
> instruction.  For these, we go back to a volatile pointer dereference
> that we had with the ACCESS_ONCE macro.

We had changed that back then because gcc 4.6 and 4.7 had a bug that could
removed the volatile statement on aggregate types like the following one

union ipte_control {
        unsigned long val;
        struct {
                unsigned long k  : 1;
                unsigned long kh : 31;
                unsigned long kg : 32;
        };
};

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145

If I see that right, your __ALIGNED_WORD(x)
macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
so it would fall back to the old volatile cast and might reintroduce the 
old compiler bug?

Could you maybe you fence your simple macro for anything older than 4.9? After
all there was no kasan support anyway on these older gcc version.

Christian

^ permalink raw reply

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
From: Joe Perches @ 2017-03-02 23:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller
In-Reply-To: <CAK8P3a2ZQR8ukt6Aky7onD2Y=b+Cz+pp+C0+Svb2EyK2474j-g@mail.gmail.com>

On Thu, 2017-03-02 at 23:59 +0100, Arnd Bergmann wrote:
> KASAN decides that passing a pointer to _m into an extern function
> (_mlog_printk) is potentially dangerous, as that function might
> keep a reference to that pointer after it goes out of scope,
> or it might not know the correct length of the stack object pointed to.
> 
> We can see from looking at the __mlog_printk() function definition
> that it's actually safe, but the compiler cannot see that when looking
> at another source file.

OK, thanks.

btw:

changing __mlog_printk can save ~11% (90+KB) of object text size
by removing __func__ and __LINE__ and using vsprintf pointer extension
%pS, __builtin_return_address(0) as it is already used in dlmmaster.

(defconfig x86-64, with ocfs2)

$ size fs/ocfs2/built-in.o*
   text	   data	    bss	    dec	    hex	filename
 759791	 111373	 105688	 976852	  ee7d4	fs/ocfs2/built-in.o.new
 852959	 111373	 105688	1070020	 1053c4	fs/ocfs2/built-in.o.old

It's nearly the same output.

---

 fs/ocfs2/cluster/masklog.c | 8 ++++----
 fs/ocfs2/cluster/masklog.h | 8 +++-----
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index d331c2386b94..a3f080f37108 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -64,8 +64,7 @@ static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
 	return count;
 }
 
-void __mlog_printk(const u64 *mask, const char *func, int line,
-		   const char *fmt, ...)
+void __mlog_printk(const u64 *mask, const char *fmt, ...)
 {
 	struct va_format vaf;
 	va_list args;
@@ -90,9 +89,10 @@ void __mlog_printk(const u64 *mask, const char *func, int line,
 	vaf.fmt = fmt;
 	vaf.va = &args;
 
-	printk("%s(%s,%u,%u):%s:%d %s%pV",
+	printk("%s(%s,%u,%u):%pS %s%pV",
 	       level, current->comm, task_pid_nr(current),
-	       raw_smp_processor_id(), func, line, prefix, &vaf);
+	       raw_smp_processor_id(), __builtin_return_address(0),
+	       prefix, &vaf);
 
 	va_end(args);
 }
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 3c16da69605d..56ba5baf625b 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -162,9 +162,8 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
 
 #endif
 
-__printf(4, 5) __nocapture(2)
-void __mlog_printk(const u64 *m, const char *func, int line,
-		   const char *fmt, ...);
+__printf(2, 3) __nocapture(2)
+void __mlog_printk(const u64 *m, const char *fmt, ...);
 
 /*
  * Testing before the __mlog_printk call lets the compiler eliminate the
@@ -174,8 +173,7 @@ void __mlog_printk(const u64 *m, const char *func, int line,
 do {									\
 	u64 _m = MLOG_MASK_PREFIX | (mask);				\
 	if (_m & ML_ALLOWED_BITS)					\
-		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
-			      ##__VA_ARGS__);				\
+		__mlog_printk(&_m, fmt, ##__VA_ARGS__);			\
 } while (0)
 
 #define mlog_errno(st) ({						\

^ permalink raw reply related

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
From: Arnd Bergmann @ 2017-03-02 22:59 UTC (permalink / raw)
  To: Joe Perches
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller
In-Reply-To: <1488494428.2179.23.camel@perches.com>

On Thu, Mar 2, 2017 at 11:40 PM, Joe Perches <joe@perches.com> wrote:
> On Thu, 2017-03-02 at 23:22 +0100, Arnd Bergmann wrote:
>> On Thu, Mar 2, 2017 at 6:46 PM, Joe Perches <joe@perches.com> wrote:
>> > On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
>> > > The internal logging infrastructure in ocfs2 causes special warning code to be
>> > > used with KASAN, which produces rather large stack frames:
>> > > fs/ocfs2/super.c: In function 'ocfs2_fill_super':
>> > > fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
>> >
>> > At least by default it doesn't seem to.
>> >
>> > gcc 6.2 allyesconfig, CONFIG_KASAN=y
>> > with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE
>> >
>> > gcc doesn't emit a stack warning
>>
>> The warning is disabled until patch 26/26. which picks the 3072 default.
>> The 3264 number was with gcc-7, which is worse than gcc-6 since it enables
>> an extra check.
>>
>> > > By simply passing the mask by value instead of reference, we can avoid the
>> > > problem completely.
>> >
>> > Any idea why that's so?
>>
>> With KASAN, every time we inline the function, the compiler has to allocate
>> space for another copy of the variable plus a redzone to detect whether
>> passing it by reference into another function causes an overflow at runtime.
>
> These logging functions aren't inlined.

Sorry, my mistake. In this case mlog() is a macro, not an inline functions.
The effect is the same though.

> You're referring to the stack frame?

The stack frame of the function that calls mlog(), yes.
>
> Still doesn't make sense to me.
>
> None of the logging functions are inlined as they are all
> EXPORT_SYMBOL.

mlog() is placed in the calling function.

> This just changes a pointer to a u64, which is the same
> size on x86-64 (and is of course larger on x86-32).

KASAN decides that passing a pointer to _m into an extern function
(_mlog_printk) is potentially dangerous, as that function might
keep a reference to that pointer after it goes out of scope,
or it might not know the correct length of the stack object pointed to.

We can see from looking at the __mlog_printk() function definition
that it's actually safe, but the compiler cannot see that when looking
at another source file.

> Perhaps KASAN has the odd behavior and working around
> KASAN's behavior may not be the proper thing to do.

Turning off KASAN fixes the problem, but the entire purpose of
KASAN is to identify code that is potentially dangerous.

> Maybe if CONFIG_KASAN is set, the minimum stack should
> be increased via THREAD_SIZE_ORDER or some such.

This is what happened in 3f181b4d8652 ("lib/Kconfig.debug:
disable -Wframe-larger-than warnings with KASAN=y").

I'm trying to revert that patch so we actually get warnings
again about functions that are still dangerous. I picked 3072
as an arbitrary limit, as there are only a handful of files
that use larger stack frames in the worst case, but we can
only use that limit after fixing up all the warnings it shows.

       Arnd

^ permalink raw reply

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
From: Arnd Bergmann @ 2017-03-02 22:22 UTC (permalink / raw)
  To: Joe Perches
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller
In-Reply-To: <1488476770.2179.6.camel@perches.com>

On Thu, Mar 2, 2017 at 6:46 PM, Joe Perches <joe@perches.com> wrote:
> On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
>> The internal logging infrastructure in ocfs2 causes special warning code to be
>> used with KASAN, which produces rather large stack frames:
>
>> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
>> fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
>
> At least by default it doesn't seem to.
>
> gcc 6.2 allyesconfig, CONFIG_KASAN=y
> with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE
>
> gcc doesn't emit a stack warning

The warning is disabled until patch 26/26. which picks the 3072 default.
The 3264 number was with gcc-7, which is worse than gcc-6 since it enables
an extra check.

>> By simply passing the mask by value instead of reference, we can avoid the
>> problem completely.
>
> Any idea why that's so?

With KASAN, every time we inline the function, the compiler has to allocate
space for another copy of the variable plus a redzone to detect whether
passing it by reference into another function causes an overflow at runtime.

>>  On 64-bit architectures, this is also more efficient,
>
> Efficient true, but the same overall stack no?

Here is what I see with CONFIG_FRAME_WARN=300 and x86_64-linux-gcc-6.3.1:

before:
fs/ocfs2/super.c: In function 'ocfs2_parse_options.isra.3':
fs/ocfs2/super.c:1508:1: error: the frame size of 352 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_enable_quotas':
fs/ocfs2/super.c:974:1: error: the frame size of 344 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 552 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

after:
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 472 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

and with gcc-7.0.1 (including -fsanitize-address-use-after-scope), before:
fs/ocfs2/super.c: In function 'ocfs2_check_volume':
fs/ocfs2/super.c:2512:1: error: the frame size of 768 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_statfs':
fs/ocfs2/super.c:1717:1: error: the frame size of 320 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_parse_options.isra.3':
fs/ocfs2/super.c:1508:1: error: the frame size of 464 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_enable_quotas':
fs/ocfs2/super.c:974:1: error: the frame size of 320 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_remount':
fs/ocfs2/super.c:752:1: error: the frame size of 568 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_initialize_super.isra.8':
fs/ocfs2/super.c:2339:1: error: the frame size of 1712 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

after:
fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 704 bytes is larger
than 300 bytes [-Werror=frame-larger-than=]

     Arnd

^ permalink raw reply

* Re: pull-request: wireless-drivers 2017-03-02
From: David Miller @ 2017-03-02 22:39 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <87r32g9gzl.fsf@kamboji.qca.qualcomm.com>

From: Kalle Valo <kvalo@codeaurora.org>
Date: Thu, 02 Mar 2017 11:15:42 +0200

> only one patch this time, the new version of ath10k patch we reverted
> earlier. I was supposed to send you this earlier but it got delayed
> because I'm on vacation, so sorry about that. I'm hoping this is ok to
> take also even the merge window is closed as the changes to the first
> version of the patch are minimal.
> 
> Please let me know if there are any problems.

Pulled, thanks.

^ permalink raw reply

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
From: Joe Perches @ 2017-03-02 22:40 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller
In-Reply-To: <CAK8P3a1gW9UqMKD2ijzxMH4rv1zAji0GUoz+bLY_oi0yvLU1cw@mail.gmail.com>

On Thu, 2017-03-02 at 23:22 +0100, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 6:46 PM, Joe Perches <joe@perches.com> wrote:
> > On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
> > > The internal logging infrastructure in ocfs2 causes special warning code to be
> > > used with KASAN, which produces rather large stack frames:
> > > fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> > > fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> > 
> > At least by default it doesn't seem to.
> > 
> > gcc 6.2 allyesconfig, CONFIG_KASAN=y
> > with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE
> > 
> > gcc doesn't emit a stack warning
> 
> The warning is disabled until patch 26/26. which picks the 3072 default.
> The 3264 number was with gcc-7, which is worse than gcc-6 since it enables
> an extra check.
> 
> > > By simply passing the mask by value instead of reference, we can avoid the
> > > problem completely.
> > 
> > Any idea why that's so?
> 
> With KASAN, every time we inline the function, the compiler has to allocate
> space for another copy of the variable plus a redzone to detect whether
> passing it by reference into another function causes an overflow at runtime.

These logging functions aren't inlined.
You're referring to the stack frame?

> > >  On 64-bit architectures, this is also more efficient,
> > 
> > Efficient true, but the same overall stack no?
> 
> Here is what I see with CONFIG_FRAME_WARN=300 and x86_64-linux-gcc-6.3.1:
> 
> before:
[]
> fs/ocfs2/super.c:1219:1: error: the frame size of 552 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]
> 
> after:
> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> fs/ocfs2/super.c:1219:1: error: the frame size of 472 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]
> 
> and with gcc-7.0.1 (including -fsanitize-address-use-after-scope), before:
[]
> fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]
> 
> after:
> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> fs/ocfs2/super.c:1219:1: error: the frame size of 704 bytes is larger
> than 300 bytes [-Werror=frame-larger-than=]

Still doesn't make sense to me.

None of the logging functions are inlined as they are all
EXPORT_SYMBOL.

This just changes a pointer to a u64, which is the same
size on x86-64 (and is of course larger on x86-32).

Perhaps KASAN has the odd behavior and working around
KASAN's behavior may not be the proper thing to do.

Maybe if CONFIG_KASAN is set, the minimum stack should
be increased via THREAD_SIZE_ORDER or some such.

^ permalink raw reply

* [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>

With CONFIG_KASAN, this driver has shown a ridiculously large stack frame
in one configuration:

drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size of 94000 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

In most builds, it's only about 3300 bytes, but that's still large anough to
risk a kernel stack overflow.

Marking the two register access functions as noinline_for_kasan avoids
the problem and brings the largest stack frame size down to 232 bytes.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index b8d3c070bfc1..fd72e5a11cb9 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
 /* ----------------------------------------------------------------------- */
 static void cx23888_std_setup(struct i2c_client *client);
 
-int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
+noinline_for_kasan int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
 {
 	u8 buffer[3];
 	buffer[0] = addr >> 8;
@@ -90,7 +90,7 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
 	return i2c_master_send(client, buffer, 3);
 }
 
-int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
+noinline_for_kasan int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
 {
 	u8 buffer[6];
 	buffer[0] = addr >> 8;
-- 
2.9.0

^ permalink raw reply related

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Arnd Bergmann @ 2017-03-02 21:45 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney
In-Reply-To: <2adc6ff4-5dc5-8f1d-cce1-47f3124a528f@de.ibm.com>

On Thu, Mar 2, 2017 at 8:00 PM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
>> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
>> <borntraeger@de.ibm.com> wrote:
>>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>>
>>>> This attempts a rewrite of the two macros, using a simpler implementation
>>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>>> 64-bit architectures) 8  byte object that can be accessed with a single
>>>> instruction.  For these, we go back to a volatile pointer dereference
>>>> that we had with the ACCESS_ONCE macro.
>>>
>>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>>> removed the volatile statement on aggregate types like the following one
>>>
>>> union ipte_control {
>>>         unsigned long val;
>>>         struct {
>>>                 unsigned long k  : 1;
>>>                 unsigned long kh : 31;
>>>                 unsigned long kg : 32;
>>>         };
>>> };
>>>
>>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>>
>>> If I see that right, your __ALIGNED_WORD(x)
>>> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
>>> so it would fall back to the old volatile cast and might reintroduce the
>>> old compiler bug?
>
> Oh dear, I should double check my sentences in emails before sending...anyway
> the full story is referenced in
>
> commit 60815cf2e05057db5b78e398d9734c493560b11e
>     Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
> which has a pointer to
> http://marc.info/?i=54611D86.4040306%40de.ibm.com
> which contains the full story.

Ok, got it. So I guess the behavior of forcing aligned accesses on aligned
data is accidental, and allowing non-power-of-two arguments is also not
the main purpose. Maybe we could just bail out on new compilers if we get
either of those? That might catch code that accidentally does something
that is inherently non-atomic or that causes a trap when the intention was
to have a simple atomic access.

     Arnd

^ permalink raw reply

* [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce stack size
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>

With CONFIG_KASAN, the init function uses a large amount of kernel stack:

drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init':
drivers/media/usb/em28xx/em28xx-dvb.c:2069:1: error: the frame size of 4280 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

By splitting out each part of the switch/case statement that has its own local
variables into a separate function, no single one of them uses more than 500 bytes,
and with a noinline_for_kasan annotation we can ensure that they are not merged
back together.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/media/usb/em28xx/em28xx-dvb.c | 947 ++++++++++++++++++----------------
 1 file changed, 508 insertions(+), 439 deletions(-)

diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 82edd37f0d73..83125a05918a 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -934,7 +934,7 @@ static struct lgdt3306a_config hauppauge_01595_lgdt3306a_config = {
 
 /* ------------------------------------------------------------------ */
 
-static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
+static noinline_for_kasan int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
 {
 	struct dvb_frontend *fe;
 	struct xc2028_config cfg;
@@ -1126,6 +1126,492 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb)
 	dvb_unregister_adapter(&dvb->adapter);
 }
 
+static noinline_for_kasan int em28174_dvb_init_pctv_460e(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_client *client;
+	struct i2c_board_info board_info;
+	struct tda10071_platform_data tda10071_pdata = {};
+	struct a8293_platform_data a8293_pdata = {};
+	int result;
+
+	/* attach demod + tuner combo */
+	tda10071_pdata.clk = 40444000, /* 40.444 MHz */
+	tda10071_pdata.i2c_wr_max = 64,
+	tda10071_pdata.ts_mode = TDA10071_TS_SERIAL,
+	tda10071_pdata.pll_multiplier = 20,
+	tda10071_pdata.tuner_i2c_addr = 0x14,
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE);
+	board_info.addr = 0x55;
+	board_info.platform_data = &tda10071_pdata;
+	request_module("tda10071");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client);
+	dvb->i2c_client_demod = client;
+
+	/* attach SEC */
+	a8293_pdata.dvb_frontend = dvb->fe[0];
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
+	board_info.addr = 0x08;
+	board_info.platform_data = &a8293_pdata;
+	request_module("a8293");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_sec = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_pctv_461e(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_client *client;
+	struct i2c_adapter *i2c_adapter;
+	struct i2c_board_info board_info;
+	struct m88ds3103_platform_data m88ds3103_pdata = {};
+	struct ts2020_config ts2020_config = {};
+	struct a8293_platform_data a8293_pdata = {};
+	int result;
+
+	/* attach demod */
+	m88ds3103_pdata.clk = 27000000;
+	m88ds3103_pdata.i2c_wr_max = 33;
+	m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
+	m88ds3103_pdata.ts_clk = 16000;
+	m88ds3103_pdata.ts_clk_pol = 1;
+	m88ds3103_pdata.agc = 0x99;
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
+	board_info.addr = 0x68;
+	board_info.platform_data = &m88ds3103_pdata;
+	request_module("m88ds3103");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client);
+	i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	ts2020_config.fe = dvb->fe[0];
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
+	board_info.addr = 0x60;
+	board_info.platform_data = &ts2020_config;
+	request_module("ts2020");
+	client = i2c_new_device(i2c_adapter, &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_tuner = client;
+	/* delegate signal strength measurement to tuner */
+	dvb->fe[0]->ops.read_signal_strength =
+			dvb->fe[0]->ops.tuner_ops.get_rf_strength;
+
+	/* attach SEC */
+	a8293_pdata.dvb_frontend = dvb->fe[0];
+	memset(&board_info, 0, sizeof(board_info));
+	strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
+	board_info.addr = 0x08;
+	board_info.platform_data = &a8293_pdata;
+	request_module("a8293");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_tuner->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_tuner);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_tuner->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_tuner);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_sec = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_pctv_292e(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+	int result;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &dvb->fe[0];
+	si2168_config.ts_mode = SI2168_TS_PARALLEL;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_terratec_t2_stick_hd(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+	int result;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &dvb->fe[0];
+	si2168_config.ts_mode = SI2168_TS_PARALLEL;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 0;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2146", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module("si2157");
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28178_dvb_init_plex_px_bcud(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct tc90522_config tc90522_config;
+	struct qm1d1c0042_config qm1d1c0042_config;
+	int result;
+
+	/* attach demod */
+	memset(&tc90522_config, 0, sizeof(tc90522_config));
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE);
+	info.addr = 0x15;
+	info.platform_data = &tc90522_config;
+	request_module("tc90522");
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_demod = client;
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	/* attach tuner */
+	memset(&qm1d1c0042_config, 0,
+	       sizeof(qm1d1c0042_config));
+	qm1d1c0042_config.fe = tc90522_config.fe;
+	qm1d1c0042_config.lpf = 1;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE);
+	info.addr = 0x61;
+	info.platform_data = &qm1d1c0042_config;
+	request_module(info.type);
+	client = i2c_new_device(tc90522_config.tuner_i2c,
+				&info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->i2c_client_tuner = client;
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	dvb->fe[0] = tc90522_config.fe;
+	px_bcud_init(dev);
+	result = 0;
+out_free:
+	return result;
+}
+
+static noinline_for_kasan int em28174_dvb_init_hauppauge_wintv_dualhd_dvb(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+	int result;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.fe = &dvb->fe[0];
+	si2168_config.ts_mode = SI2168_TS_SERIAL;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	result = 0;
+out_free:
+	return result;
+}
+
+static int em28174_dvb_init_hauppauge_wintv_dualhd_01595(struct em28xx *dev)
+{
+	struct em28xx_dvb *dvb = dev->dvb;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info info = {};
+	struct lgdt3306a_config lgdt3306a_config;
+	struct si2157_config si2157_config = {};
+	int result;
+
+	/* attach demod */
+	lgdt3306a_config = hauppauge_01595_lgdt3306a_config;
+	lgdt3306a_config.fe = &dvb->fe[0];
+	lgdt3306a_config.i2c_adapter = &adapter;
+	strlcpy(info.type, "lgdt3306a", sizeof(info.type));
+	info.addr = 0x59;
+	info.platform_data = &lgdt3306a_config;
+	request_module(info.type);
+	client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus],
+			&info);
+	if (client == NULL || client->dev.driver == NULL) {
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_demod = client;
+
+	/* attach tuner */
+	si2157_config.fe = dvb->fe[0];
+	si2157_config.if_port = 1;
+	si2157_config.inversion = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	si2157_config.mdev = dev->media_dev;
+#endif
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2157", sizeof(info.type));
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+	request_module(info.type);
+
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL || client->dev.driver == NULL) {
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+	if (!try_module_get(client->dev.driver->owner)) {
+		i2c_unregister_device(client);
+		module_put(dvb->i2c_client_demod->dev.driver->owner);
+		i2c_unregister_device(dvb->i2c_client_demod);
+		result = -ENODEV;
+		goto out_free;
+	}
+
+	dvb->i2c_client_tuner = client;
+	result = 0;
+out_free:
+	return result;
+}
 static int em28xx_dvb_init(struct em28xx *dev)
 {
 	int result = 0;
@@ -1427,60 +1913,11 @@ static int em28xx_dvb_init(struct em28xx *dev)
 				   &dev->i2c_adap[dev->def_i2c_bus],
 				   &c3tech_duo_tda18271_config);
 		break;
-	case EM28174_BOARD_PCTV_460E: {
-		struct i2c_client *client;
-		struct i2c_board_info board_info;
-		struct tda10071_platform_data tda10071_pdata = {};
-		struct a8293_platform_data a8293_pdata = {};
-
-		/* attach demod + tuner combo */
-		tda10071_pdata.clk = 40444000, /* 40.444 MHz */
-		tda10071_pdata.i2c_wr_max = 64,
-		tda10071_pdata.ts_mode = TDA10071_TS_SERIAL,
-		tda10071_pdata.pll_multiplier = 20,
-		tda10071_pdata.tuner_i2c_addr = 0x14,
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE);
-		board_info.addr = 0x55;
-		board_info.platform_data = &tda10071_pdata;
-		request_module("tda10071");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			result = -ENODEV;
-			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client);
-		dvb->i2c_client_demod = client;
-
-		/* attach SEC */
-		a8293_pdata.dvb_frontend = dvb->fe[0];
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
-		board_info.addr = 0x08;
-		board_info.platform_data = &a8293_pdata;
-		request_module("a8293");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
+	case EM28174_BOARD_PCTV_460E:
+		result = em28174_dvb_init_pctv_460e(dev);
+		if (result)
 			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->i2c_client_sec = client;
 		break;
-	}
 	case EM2874_BOARD_DELOCK_61959:
 	case EM2874_BOARD_MAXMEDIA_UB425_TC:
 		/* attach demodulator */
@@ -1626,403 +2063,35 @@ static int em28xx_dvb_init(struct em28xx *dev)
 			}
 		}
 		break;
-	case EM28178_BOARD_PCTV_461E: {
-		struct i2c_client *client;
-		struct i2c_adapter *i2c_adapter;
-		struct i2c_board_info board_info;
-		struct m88ds3103_platform_data m88ds3103_pdata = {};
-		struct ts2020_config ts2020_config = {};
-		struct a8293_platform_data a8293_pdata = {};
-
-		/* attach demod */
-		m88ds3103_pdata.clk = 27000000;
-		m88ds3103_pdata.i2c_wr_max = 33;
-		m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
-		m88ds3103_pdata.ts_clk = 16000;
-		m88ds3103_pdata.ts_clk_pol = 1;
-		m88ds3103_pdata.agc = 0x99;
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
-		board_info.addr = 0x68;
-		board_info.platform_data = &m88ds3103_pdata;
-		request_module("m88ds3103");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			result = -ENODEV;
+	case EM28178_BOARD_PCTV_461E: 
+		result = em28178_dvb_init_pctv_461e(dev);
+		if (result)
 			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client);
-		i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);
-		dvb->i2c_client_demod = client;
-
-		/* attach tuner */
-		ts2020_config.fe = dvb->fe[0];
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
-		board_info.addr = 0x60;
-		board_info.platform_data = &ts2020_config;
-		request_module("ts2020");
-		client = i2c_new_device(i2c_adapter, &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->i2c_client_tuner = client;
-		/* delegate signal strength measurement to tuner */
-		dvb->fe[0]->ops.read_signal_strength =
-				dvb->fe[0]->ops.tuner_ops.get_rf_strength;
-
-		/* attach SEC */
-		a8293_pdata.dvb_frontend = dvb->fe[0];
-		memset(&board_info, 0, sizeof(board_info));
-		strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
-		board_info.addr = 0x08;
-		board_info.platform_data = &a8293_pdata;
-		request_module("a8293");
-		client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info);
-		if (client == NULL || client->dev.driver == NULL) {
-			module_put(dvb->i2c_client_tuner->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_tuner);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		if (!try_module_get(client->dev.driver->owner)) {
-			i2c_unregister_device(client);
-			module_put(dvb->i2c_client_tuner->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_tuner);
-			module_put(dvb->i2c_client_demod->dev.driver->owner);
-			i2c_unregister_device(dvb->i2c_client_demod);
-			result = -ENODEV;
-			goto out_free;
-		}
-		dvb->i2c_client_sec = client;
 		break;
-	}
 	case EM28178_BOARD_PCTV_292E:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct si2168_config si2168_config;
-			struct si2157_config si2157_config;
-
-			/* attach demod */
-			memset(&si2168_config, 0, sizeof(si2168_config));
-			si2168_config.i2c_adapter = &adapter;
-			si2168_config.fe = &dvb->fe[0];
-			si2168_config.ts_mode = SI2168_TS_PARALLEL;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-			info.addr = 0x64;
-			info.platform_data = &si2168_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			memset(&si2157_config, 0, sizeof(si2157_config));
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 1;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module(info.type);
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-			dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
-		}
+		result = em28178_dvb_init_pctv_292e(dev);
+		if (result)
+			goto out_free;
 		break;
 	case EM28178_BOARD_TERRATEC_T2_STICK_HD:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct si2168_config si2168_config;
-			struct si2157_config si2157_config;
-
-			/* attach demod */
-			memset(&si2168_config, 0, sizeof(si2168_config));
-			si2168_config.i2c_adapter = &adapter;
-			si2168_config.fe = &dvb->fe[0];
-			si2168_config.ts_mode = SI2168_TS_PARALLEL;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-			info.addr = 0x64;
-			info.platform_data = &si2168_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			memset(&si2157_config, 0, sizeof(si2157_config));
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 0;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2146", I2C_NAME_SIZE);
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module("si2157");
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-		}
+		result = em28178_dvb_init_terratec_t2_stick_hd(dev);
+		if (result)
+			goto out_free;
 		break;
-
 	case EM28178_BOARD_PLEX_PX_BCUD:
-		{
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct tc90522_config tc90522_config;
-			struct qm1d1c0042_config qm1d1c0042_config;
-
-			/* attach demod */
-			memset(&tc90522_config, 0, sizeof(tc90522_config));
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE);
-			info.addr = 0x15;
-			info.platform_data = &tc90522_config;
-			request_module("tc90522");
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-			dvb->i2c_client_demod = client;
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			/* attach tuner */
-			memset(&qm1d1c0042_config, 0,
-			       sizeof(qm1d1c0042_config));
-			qm1d1c0042_config.fe = tc90522_config.fe;
-			qm1d1c0042_config.lpf = 1;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE);
-			info.addr = 0x61;
-			info.platform_data = &qm1d1c0042_config;
-			request_module(info.type);
-			client = i2c_new_device(tc90522_config.tuner_i2c,
-						&info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-			dvb->i2c_client_tuner = client;
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-			dvb->fe[0] = tc90522_config.fe;
-			px_bcud_init(dev);
-		}
+		result = em28178_dvb_init_plex_px_bcud(dev);
+		if (result)
+			goto out_free;
 		break;
 	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info;
-			struct si2168_config si2168_config;
-			struct si2157_config si2157_config;
-
-			/* attach demod */
-			memset(&si2168_config, 0, sizeof(si2168_config));
-			si2168_config.i2c_adapter = &adapter;
-			si2168_config.fe = &dvb->fe[0];
-			si2168_config.ts_mode = SI2168_TS_SERIAL;
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-			info.addr = 0x64;
-			info.platform_data = &si2168_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			memset(&si2157_config, 0, sizeof(si2157_config));
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 1;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module(info.type);
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-
-		}
+		result = em28174_dvb_init_hauppauge_wintv_dualhd_dvb(dev);
+		if (result)
+			goto out_free;
 		break;
 	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
-		{
-			struct i2c_adapter *adapter;
-			struct i2c_client *client;
-			struct i2c_board_info info = {};
-			struct lgdt3306a_config lgdt3306a_config;
-			struct si2157_config si2157_config = {};
-
-			/* attach demod */
-			lgdt3306a_config = hauppauge_01595_lgdt3306a_config;
-			lgdt3306a_config.fe = &dvb->fe[0];
-			lgdt3306a_config.i2c_adapter = &adapter;
-			strlcpy(info.type, "lgdt3306a", sizeof(info.type));
-			info.addr = 0x59;
-			info.platform_data = &lgdt3306a_config;
-			request_module(info.type);
-			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus],
-					&info);
-			if (client == NULL || client->dev.driver == NULL) {
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_demod = client;
-
-			/* attach tuner */
-			si2157_config.fe = dvb->fe[0];
-			si2157_config.if_port = 1;
-			si2157_config.inversion = 1;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-			si2157_config.mdev = dev->media_dev;
-#endif
-			memset(&info, 0, sizeof(struct i2c_board_info));
-			strlcpy(info.type, "si2157", sizeof(info.type));
-			info.addr = 0x60;
-			info.platform_data = &si2157_config;
-			request_module(info.type);
-
-			client = i2c_new_device(adapter, &info);
-			if (client == NULL || client->dev.driver == NULL) {
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-			if (!try_module_get(client->dev.driver->owner)) {
-				i2c_unregister_device(client);
-				module_put(dvb->i2c_client_demod->dev.driver->owner);
-				i2c_unregister_device(dvb->i2c_client_demod);
-				result = -ENODEV;
-				goto out_free;
-			}
-
-			dvb->i2c_client_tuner = client;
-		}
+		result = em28174_dvb_init_hauppauge_wintv_dualhd_01595(dev);
+		if (result)
+			goto out_free;
 		break;
 	default:
 		dev_err(&dev->intf->dev,
-- 
2.9.0

^ permalink raw reply related

* Re: Usage of WoWLAN with iwlwifi driver (Device phy0 failed to suspend async: error -16)
From: Johannes Berg @ 2017-03-02 18:38 UTC (permalink / raw)
  To: Oliver Freyermuth, linux-wireless
In-Reply-To: <0cd984fd-3d26-15b2-03ce-69cdb7c0e434@googlemail.com>


> > Yes. Does it print something to that effect at resume time? I think
> > it should.
> 
> Oh yes - I totally missed that since it came quite late in the resume
> cycle:
> 
> [12386.085899] iwlwifi 0000:0a:00.0: System wakeup disabled by ACPI
> [12386.088449] iwlwifi 0000:0a:00.0: Device was reset during suspend
> 
> I guess the "Device was reset during suspend" means my firmware did
> something uncool like cutting the power to it (it's a laptop, but I
> suspended with power supply staying connected). 

Yes.

> UEFI options are very limited, so I guess I'm just out of luck with
> this hardware. 

Yeah, most likely.

> I have another laptop with the same iwlwifi card (but newer HW
> revision), a comparable Gentoo 
> installation but with an unlocked UEFI. 
> I'll play with it on the weekend and report back in case I find
> anything different there. 

Ok. I *have* gotten this to work on some (old) laptops, but not
generally.

johannes

^ permalink raw reply

* [PATCH 24/26] ocfs2: reduce stack size with KASAN
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann, Joe Perches
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>

The internal logging infrastructure in ocfs2 causes special warning code to be
used with KASAN, which produces rather large stack frames:

fs/ocfs2/super.c: In function 'ocfs2_fill_super':
fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

By simply passing the mask by value instead of reference, we can avoid the
problem completely. On 64-bit architectures, this is also more efficient,
while on the less common (at least among ocfs2 users) 32-bit architectures,
I'm guessing that the resulting code is comparable to what it was before.

The current version was introduced by Joe Perches as an optimization, maybe
he can see if my change regresses compared to his.

Cc: Joe Perches <joe@perches.com>
Fixes: 7c2bd2f930ae ("ocfs2: reduce object size of mlog uses")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 fs/ocfs2/cluster/masklog.c | 10 +++++-----
 fs/ocfs2/cluster/masklog.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index d331c2386b94..9720c5443e4d 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -64,7 +64,7 @@ static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
 	return count;
 }
 
-void __mlog_printk(const u64 *mask, const char *func, int line,
+void __mlog_printk(const u64 mask, const char *func, int line,
 		   const char *fmt, ...)
 {
 	struct va_format vaf;
@@ -72,14 +72,14 @@ void __mlog_printk(const u64 *mask, const char *func, int line,
 	const char *level;
 	const char *prefix = "";
 
-	if (!__mlog_test_u64(*mask, mlog_and_bits) ||
-	    __mlog_test_u64(*mask, mlog_not_bits))
+	if (!__mlog_test_u64(mask, mlog_and_bits) ||
+	    __mlog_test_u64(mask, mlog_not_bits))
 		return;
 
-	if (*mask & ML_ERROR) {
+	if (mask & ML_ERROR) {
 		level = KERN_ERR;
 		prefix = "ERROR: ";
-	} else if (*mask & ML_NOTICE) {
+	} else if (mask & ML_NOTICE) {
 		level = KERN_NOTICE;
 	} else {
 		level = KERN_INFO;
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 308ea0eb35fd..0d0f4bf2c3d8 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -163,7 +163,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
 #endif
 
 __printf(4, 5)
-void __mlog_printk(const u64 *m, const char *func, int line,
+void __mlog_printk(const u64 m, const char *func, int line,
 		   const char *fmt, ...);
 
 /*
@@ -174,7 +174,7 @@ void __mlog_printk(const u64 *m, const char *func, int line,
 do {									\
 	u64 _m = MLOG_MASK_PREFIX | (mask);				\
 	if (_m & ML_ALLOWED_BITS)					\
-		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
+		__mlog_printk(_m, __func__, __LINE__, fmt,		\
 			      ##__VA_ARGS__);				\
 } while (0)
 
-- 
2.9.0

^ permalink raw reply related

* Re: Usage of WoWLAN with iwlwifi driver (Device phy0 failed to suspend async: error -16)
From: Oliver Freyermuth @ 2017-03-02 18:20 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless
In-Reply-To: <1488444909.8390.11.camel@sipsolutions.net>

Am 02.03.2017 um 09:55 schrieb Johannes Berg:
>> The problem is that it seems I cannot actually wake the machine
>> anymore afterwards... 
>> While in the suspend procedure, I see:
>> [12385.893568] iwlwifi 0000:0a:00.0: System wakeup enabled by ACPI
>> as expected, I could neither get it to make a tcp connection in tcp-
>> connection mode,
>> nor could I wake the machine via magic packet in magic-packet mode. 
>>
>> Could that be some hardware / system firmware limitation, e.g. if my
>> UEFI does not support actually powering
>> the WiFi hardware if I am in S3?
> 
> Yes. Does it print something to that effect at resume time? I think it
> should.
Oh yes - I totally missed that since it came quite late in the resume cycle:

[12386.085899] iwlwifi 0000:0a:00.0: System wakeup disabled by ACPI
[12386.088449] iwlwifi 0000:0a:00.0: Device was reset during suspend

I guess the "Device was reset during suspend" means my firmware did something uncool
like cutting the power to it (it's a laptop, but I suspended with power supply staying connected). 
UEFI options are very limited, so I guess I'm just out of luck with this hardware. 

I have another laptop with the same iwlwifi card (but newer HW revision), a comparable Gentoo 
installation but with an unlocked UEFI. 
I'll play with it on the weekend and report back in case I find anything different there. 

>> At least, the suspend problem seems to be clearly related to some
>> path only used if CONFIG_IWLWIFI_PCIE_RTPM is on. 
> 
> Would you mind filing a bug on bugzilla.kernel.org (and adding linuxwif
> i@intel.com as the assignee or at least in Cc)? I think we really ought
> to sort out the issues with the RTPM stuff.
Good idea, I'll do that over the weekend. 

Thanks a lot for the support! 
	Oliver

> 
> johannes
> 

^ permalink raw reply

* [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with KASAN
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>

Enabling CONFIG_KASAN can lead to an instant stack overflow:

drivers/gpu/drm/i915/gvt/handlers.c: In function 'init_generic_mmio_info':
drivers/gpu/drm/i915/gvt/handlers.c:2200:1: error: the frame size of 30464 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/gpu/drm/i915/gvt/handlers.c: In function 'init_broadwell_mmio_info':
drivers/gpu/drm/i915/gvt/handlers.c:2402:1: error: the frame size of 5376 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
drivers/gpu/drm/i915/gvt/handlers.c: In function 'init_skl_mmio_info':
drivers/gpu/drm/i915/gvt/handlers.c:2628:1: error: the frame size of 5296 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

The reason is the INTEL_GVT_MMIO_OFFSET() hack that attempts to convert any type
(including i915_reg_t) into a u32 by reading the first four bytes, in combination
with the stack sanitizer that adds a redzone around each instance.

Originally, i915_reg_t was introduced to add a little extra type safety by
disallowing simple type casts, and INTEL_GVT_MMIO_OFFSET() goes the opposite
way by allowing any type as input, including those that are not safe in this
context.

I'm replacing it with an implementation that specifically allows the three
types that are actually used as input: 'i915_reg_t' (from _MMIO constants),
'int' (from other constants), and 'unsigned int' (from function arguments),
and any other type should now provoke a build error. This also solves the
stack overflow as we no longer use a local variable for each instance.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/gpu/drm/i915/gvt/mmio.h | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h
index 3bc620f56f35..bf40100fc626 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.h
+++ b/drivers/gpu/drm/i915/gvt/mmio.h
@@ -78,13 +78,20 @@ bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);
 int intel_gvt_setup_mmio_info(struct intel_gvt *gvt);
 void intel_gvt_clean_mmio_info(struct intel_gvt *gvt);
 
+static inline u32 intel_gvt_mmio_offset(unsigned int offset)
+{
+	return offset;
+}
+
 struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt,
 						     unsigned int offset);
-#define INTEL_GVT_MMIO_OFFSET(reg) ({ \
-	typeof(reg) __reg = reg; \
-	u32 *offset = (u32 *)&__reg; \
-	*offset; \
-})
+#define INTEL_GVT_MMIO_OFFSET(reg) \
+__builtin_choose_expr(__builtin_types_compatible_p(typeof(reg), int), intel_gvt_mmio_offset, \
+__builtin_choose_expr(__builtin_types_compatible_p(typeof(reg), unsigned int), intel_gvt_mmio_offset, \
+__builtin_choose_expr(__builtin_types_compatible_p(typeof(reg), i915_reg_t), i915_mmio_reg_offset, \
+	(void)(0) \
+)))(reg)
+
 
 int intel_vgpu_init_mmio(struct intel_vgpu *vgpu);
 void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu);
-- 
2.9.0

^ permalink raw reply related

* RE: [PATCH v2] mac80211: Jitter HWMP MPATH reply frames to reduce collision on dense networks.
From: Jesse Jones @ 2017-03-02 17:41 UTC (permalink / raw)
  To: Johannes Berg, agreen, linux-wireless; +Cc: Jesse Jones
In-Reply-To: <1488443814.8390.3.camel@sipsolutions.net>

> Hi Alexis,
>
> > This is loosely based on RFC5148, specifically event-triggered message
> > generation as described in section 5.2.
>
> I'm confused. I see how that generally seems to apply to any mobile
> network, but it *does* state up-front that
>     In some instances, these problems can be solved in these lower
>     layers, but in other instances, some help at the network and higher
>     layers is necessary.
>
> I believe 802.11 *does* in fact solve these issues at lower layers. Can
> you explain how you observed any problem in this area?

Well it certainly attempts to via stuff like carrier sense. But that is not
fool proof and any time two routers hear a frame and both decide to forward
it immediately there is a chance that they will both sense the air at the
same time, decide that it is clear, and lose both their forwarded frames due
to a collision. How often that happens is hard to say but we have observed
that exact behavior a few years ago with an 802.11 multicast routing
protocol and adding jitter significantly improved reliability.

An example of where this would be solved at a lower layer would be something
like a TDMA network that has better mechanisms to ensure that multiple
devices do not send at the same time.

> > The frames are not duplicated, but, hopefully offset enough so they
> > don't collide at the receiver
>
> That wasn't my question - my question regarding duplicating was if this
> was
> intended to *suppress* duplicates, but it sounds like not.

No, it's not intended to suppress duplicates.

  -- Jesse

^ permalink raw reply

* [PATCH 3/4] Staging:wilc1000:wilc_spi: Fixed spelling error
From: Georgios Emmanouil @ 2017-03-02 17:06 UTC (permalink / raw)
  To: aditya.shankar, ganesh.krishna, gregkh
  Cc: linux-wireless, devel, linux-kernel
In-Reply-To: <1488474328-15992-1-git-send-email-geo.emmnl@gmail.com>

Fixed spelling error. 'unkmown' to 'unknown'.

Signed-off-by: Georgios Emmanouil <geo.emmnl@gmail.com>
---
 drivers/staging/wilc1000/wilc_spi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index b48cb1c8..4f38922 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -963,12 +963,12 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
 				}

 				{
-					u32 unkmown_mask;
+					u32 unknown_mask;

-					unkmown_mask = ~((1ul << g_spi.nint) - 1);
+					unknown_mask = ~((1ul << g_spi.nint) - 1);

-					if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
-						dev_err(&spi->dev, "Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
+					if ((tmp >> IRG_FLAGS_OFFSET) & unknown_mask) {
+						dev_err(&spi->dev, "Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unknown_mask);
 						happended = 1;
 					}
 				}
--
2.1.4

^ permalink raw reply related

* [PATCH 2/4] Staging:wilc1000:wilc_spi: Fixed alignment to match parenthesis
From: Georgios Emmanouil @ 2017-03-02 17:05 UTC (permalink / raw)
  To: aditya.shankar, ganesh.krishna, gregkh
  Cc: linux-wireless, devel, linux-kernel
In-Reply-To: <1488474268-15876-1-git-send-email-geo.emmnl@gmail.com>

Fixed alignment to match parenthesis.

Signed-off-by: Georgios Emmanouil <geo.emmnl@gmail.com>
---
 drivers/staging/wilc1000/wilc_spi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index 6bd4047..b48cb1c8 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -408,7 +408,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,

 	if (len2 > ARRAY_SIZE(wb)) {
 		dev_err(&spi->dev, "spi buffer size too small (%d) (%zu)\n",
-			 len2, ARRAY_SIZE(wb));
+			len2, ARRAY_SIZE(wb));
 		return N_FAIL;
 	}
 	/* zero spi write buffers. */
--
2.1.4

^ permalink raw reply related

* Problem regarding wifi device with network namespaces
From: Tim Löpmeier @ 2017-03-02 17:18 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org

SGksDQoNCkknbSBmYWNpbmcgc29tZSBwcm9ibGVtcyB3aXRoIG5ldHdvcmsgbmFtZXNwYWNlcyBh
bmQgd2lyZWxlc3MgZGV2aWNlcy4gDQpJZiBJIG1vdmUgYSBuZXR3b3JrIHBoeXNpY2FsIGRldmlj
ZSBpbnRvIGEgbmV0d29yayBuYW1lc3BhY2UgYW5kIHRoZW4gDQp0cnkgdG8gZG8gYW55IG9wZXJh
dGlvbiBvbiB0aGUgcGh5LCBpdCB3aWxsIGFsd2F5cyByZXN1bHQgaW50byAiY29tbWFuZCANCmZh
aWxlZDogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSAoLTIpIiBvY2N1cmVzLiBGb3IgYWRkaXRp
b25hbCANCmluZm9ybWF0aW9ucyBzZWUgYmVsb3cuDQoNCkkgdGhpbmsgdGhpcyBpcyBhIGJ1Zywg
YnV0IG1heWJlIHRoZXJlIGlzIGEgZ29vZCByZWFzb24gZm9yIHRoaXMuIElmIA0KaXQncyBub3Qg
YSBidWcsIGRvIHlvdSBoYXZlIGFueSBpZGVhIGZvciBhIHdvcmthcm91bmQ/IEkgbmVlZCBhIHdv
cmtpbmcgDQogPml3PCBpbnNpZGUgYSBuZXR3b3JrIG5hbWVzcGFjZSAoZS5nLiBzc2hkIGluIGEg
ZG9ja2VyLWNvbnRhaW5lcikuDQoNClRoYW5rcyBpbiBhZHZhbmNlLA0KVGltDQoNClBTOiBQbGVh
c2Uga2VlcCBtZSBpbiBDQyBvciBzZW5kIG1lIGEgcXVpY2sgbWVzc2FnZSBpZiBJIG5lZWQgdG8g
DQpzdWJzY3JpYmUgdG8gdGhlIG1haWxpbmdsaXN0IHRvIGZvbGxvdyB0aGUgdGhyZWFkLg0KDQoN
Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCkhvdyB0byByZXBy
b2R1Y2U/DQoNCiNGaXJzdCB1bnNoYXJlIGEgcHJvY2VzcywgZS5nLiBhIGJhc2gNCiA+IHVuc2hh
cmUgLW4gYmFzaA0KI0dldCBpdCdzIHByb2Nlc3MgaWQNCiA+IGVjaG8gJCQNCg0KI2luIGFuIG90
aGVyIHRlcm1pbmFsDQojTW92ZSBwaHkgdG8gcHJvY2VzcyBuZXR3b3JrIG5hbWVzcGFjZQ0KID4g
aXcgcGh5IHBoeTAgc2V0IG5ldG5zICVQUk9DRVNTSUQlDQoNCiNpbiBmaXJzdCB0ZXJtaW5hbCAo
dW5zaGFyZWQgYmFzaCkNCiNkbyBhbnkgcGh5IG9wZXJhdGlvbg0KID4gaXcgcGh5IHBoeTAgaW5m
bw0KI0xlYWRzIHRvOiBjb21tYW5kIGZhaWxlZDogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSAo
LTIpDQojYW55IGRldmljZSByZWxhdGVkIGNvbW1hbmRzIHN0aWxsIHdvcmsNCiA+IGl3IGRldiB3
bGFuMCBpbmZvDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoN
CkFkZGl0aW9uYWwgaW5mb3JtYXRpb246DQoNCklmIEkgdXNlIGlwIG5ldG5zIGV4ZWMgaXQncyB3
b3JraW5nOg0KDQojbmV0bnMgaXMgb25seSB3b3JraW5nIHdpdGggbmFtZWQgbmV0d29ya3Mgc28g
bGV0J3MgY3JlYXRlIG9uZQ0KID4gbG4gLXNmIC9wcm9jLyVQUk9DRVNTSUQlL25zL25ldCAvdmFy
L3J1bi9uZXRucy90ZXN0DQogPiBpdyBwaHkgcGh5MCBzZXQgbmV0bnMgJVBST0NFU1NJRCUNCiN3
b3Jrcw0KID4gaXAgbmV0bnMgZXhlYyB0ZXN0IGl3IHBoeSBwaHkwIGluZm8NCiNTdGlsbCBkb2Vz
bid0IHdvcmssIGNhbiBhbHNvIGJlIGNhbGxlZCBpbiB1bnNoYXJlZCBiYXNoIHRlcm1pbmFsDQog
PiBuc2VudGVyIC10ICVQUk9DRVNTSUQlIC1uIGl3IHBoeSBwaHkwIGluZm8NCg0KTWF5YmUgaGVs
cGZ1bDoNCg0KID4gaXAgbmV0bnMgZXhlYyB0ZXN0IGZpbmQgL3N5cy9jbGFzcy9pZWVlODAyMTEv
IHwgZ3JlcCBwaHkwDQojZmluZHMgL3N5cy9jbGFzcy9pZWVlODAyMTEvcGh5MA0KDQogPiBuc2Vu
dGVyIC10ICVQUk9DRVNTSUQlIC1uIGZpbmQgL3N5cy9jbGFzcy9pZWVlODAyMTEvIHwgZ3JlcCBw
aHkwDQojbm8gcmVzdWx0DQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tDQoNCktlcm5lbCB2ZXJzaW9uIGV0YzoNCg0KVGhpcyBwcm9ibGVtIG9jY3VycyB3aXRoIHZh
bmlsbGEga2VybmVsIDQuMTAuMSB4ODZfNjQgKHN0YWJsZSksIGl3IA0KdmVyc2lvbiA0LjkgYW5k
IHZhcmlvdXMgd2lmaSBkZXZpY2VzIChJbnRlbCA3MjYwLCBtYWM4MDIxMV9od3NpbSwgDQpBdGhl
cm9zIEFSNTQxMykuIEkgYWxzbyB0cmllZCBvbGRlciBkaXN0cm8ga2VybmVscy4NCg0K

^ permalink raw reply

* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Arnd Bergmann @ 2017-03-02 17:55 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
	Networking, Linux Kernel Mailing List, linux-media,
	linux-wireless, kernel-build-reports, David S . Miller,
	Paul McKenney
In-Reply-To: <76790664-a7a9-193c-2e30-edaee1308cb0@de.ibm.com>

On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>
>> This attempts a rewrite of the two macros, using a simpler implementation
>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>> 64-bit architectures) 8  byte object that can be accessed with a single
>> instruction.  For these, we go back to a volatile pointer dereference
>> that we had with the ACCESS_ONCE macro.
>
> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
> removed the volatile statement on aggregate types like the following one
>
> union ipte_control {
>         unsigned long val;
>         struct {
>                 unsigned long k  : 1;
>                 unsigned long kh : 31;
>                 unsigned long kg : 32;
>         };
> };
>
> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>
> If I see that right, your __ALIGNED_WORD(x)
> macro would say that for above structure  sizeof(x) == sizeof(long)) is true,
> so it would fall back to the old volatile cast and might reintroduce the
> old compiler bug?

Ah, right, that's the missing piece. For some reason I didn't find
the reference in the source or the git log.

> Could you maybe you fence your simple macro for anything older than 4.9? After
> all there was no kasan support anyway on these older gcc version.

Yes, that should work, thanks!

     Arnd

^ permalink raw reply

* Re: [PATCH 24/26] ocfs2: reduce stack size with KASAN
From: Joe Perches @ 2017-03-02 17:46 UTC (permalink / raw)
  To: Arnd Bergmann, kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller
In-Reply-To: <20170302163834.2273519-25-arnd@arndb.de>

On Thu, 2017-03-02 at 17:38 +0100, Arnd Bergmann wrote:
> The internal logging infrastructure in ocfs2 causes special warning code to be
> used with KASAN, which produces rather large stack frames:

> fs/ocfs2/super.c: In function 'ocfs2_fill_super':
> fs/ocfs2/super.c:1219:1: error: the frame size of 3264 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

At least by default it doesn't seem to.

gcc 6.2 allyesconfig, CONFIG_KASAN=y
with either CONFIG_KASAN_INLINE or CONFIG_KASAN_OUTLINE

gcc doesn't emit a stack warning

> By simply passing the mask by value instead of reference, we can avoid the
> problem completely.

Any idea why that's so?
 
>  On 64-bit architectures, this is also more efficient,

Efficient true, but the same overall stack no?

> while on the less common (at least among ocfs2 users) 32-bit architectures,
> I'm guessing that the resulting code is comparable to what it was before.
> 
> The current version was introduced by Joe Perches as an optimization, maybe
> he can see if my change regresses compared to his.

I don't see it.

> Cc: Joe Perches <joe@perches.com>
> Fixes: 7c2bd2f930ae ("ocfs2: reduce object size of mlog uses")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  fs/ocfs2/cluster/masklog.c | 10 +++++-----
>  fs/o cfs2/cluster/masklog.h |  4 ++--
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
> index d331c2386b94..9720c5443e4d 100644
> --- a/fs/ocfs2/cluster/masklog.c
> +++ b/fs/ocfs2/cluster/masklog.c
> @@ -64,7 +64,7 @@ static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
>  	return count;
>  }
>  
> -void __mlog_printk(const u64 *mask, const char *func, int line,
> +void __mlog_printk(const u64 mask, const char *func, int line,
>  		   const char *fmt, ...)
>  {
>  	struct va_format vaf;
> @@ -72,14 +72,14 @@ void __mlog_printk(const u64 *mask, const char *func, int line,
>  	const char *level;
>  	const char *prefix = "";
>  
> -	if (!__mlog_test_u64(*mask, mlog_and_bits) ||
> -	    __mlog_test_u64(*mask, mlog_not_bits))
> +	if (!__mlog_test_u64(mask, mlog_and_bits) ||
> +	    __mlog_test_u64(mask, mlog_not_bits))
>  		return;
>  
> -	if (*mask & ML_ERROR) {
> +	if (mask & ML_ERROR) {
>  		level = KERN_ERR;
>  		prefix = "ERROR: ";
> -	} else if (*mask & ML_NOTICE) {
> +	} else if (mask & ML_NOTICE) {
>  		level = KERN_NOTICE;
>  	} else {
>  		level = KERN_INFO;
> diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
> index 308ea0eb35fd..0d0f4bf2c3d8 100644
> --- a/fs/ocfs2/cluster/masklog.h
> +++ b/fs/ocfs2/cluster/masklog.h
> @@ -163,7 +163,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
>  #endif
>  
>  __printf(4, 5)
> -void __mlog_printk(const u64 *m, const char *func, int line,
> +void __mlog_printk(const u64 m, const char *func, int line,
>  		   const char *fmt, ...);
>  
>  /*
> @@ -174,7 +174,7 @@ void __mlog_printk(const u64 *m, const char *func, int line,
>  do {									\
>  	u64 _m = MLOG_MASK_PREFIX | (mask);				\
>  	if (_m & ML_ALLOWED_BITS)					\
> -		__mlog_printk(&_m, __func__, __LINE__, fmt,		\
> +		__mlog_printk(_m, __func__, __LINE__, fmt,		\
>  			      ##__VA_ARGS__);				\
>  } while (0)
>  

^ permalink raw reply

* RE: [PATCH v2] mac80211: mesh - always do every discovery retry
From: Jesse Jones @ 2017-03-02 17:32 UTC (permalink / raw)
  To: Chun-Yeow Yeoh, linux-wireless, Alexis Green, Alexis Green
In-Reply-To: <CAEFj984umxKZgMqzgbQvX+VgPjqCW98E17bfED9+Yg3XGzatOw@mail.gmail.com>

> > Instead of stopping path discovery when a path is found continue
> > attempting to find paths until we hit the dot11MeshHWMPmaxPREQretries
> > limit.
>
> I am not too sure whether by simply broadcasting the PREQ frame could
> actually solve the problem and this may cause problem of PREQ flooding in
> your network when the number of nodes scale. Please take note that all
> nodes need to rebroadcast the PREQ frame until target STA.

Yes, that is a real issue. We are planning on doing some further work in
this area to  try to minimize the explosions that can be seen with PREQs in
larger networks while balancing the need for reliability.

Path discovery
> should stop once the path is established. By attempting 2nd, 3rd or 4th
> doesn't guarantee the next path will be "good".

It doesn't guarantee anything of course but it does raise the probability
that the right path will be found. For example take four nodes in a ring
where the A-B, B-C, C-D links are all good but the A-D link is poor. Poor
enough that the higher data rates are hosed for that link but the basic rate
used by management frames is relatively unaffected. If we assume that the
reliability of management frames is 90% then in order for A to route to D it
needs to get a PREQ to D and a PREP back. It has two options 1) for A-D the
reliability will be 0.9^2 = 81% 2) for A-B-C-D the reliability will be 0.9^6
= 53%.

This isn't a good situation because it makes it much too easy for routing to
pick a *really* bad path. And we have seen reliability improvements with
this patch.

We have already made changes to dial way back on the number of PREQs sent
out so this patch made quite a bit of sense for us. In the default
configuration where PREQs go out every 4s I don't think we have a good
solution: picking a bad path, even for 4s, can be a horrible user experience
but PREQ volumes quickly start consuming too much airtime as network sizes
increase.

  -- Jesse

^ permalink raw reply

* [PATCH 23/26] mtd: cfi: reduce stack size with KASAN
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>

When CONFIG_KASAN is used, we consume a lot of extra stack space:

drivers/mtd/chips/cfi_cmdset_0020.c: In function 'do_write_buffer':
drivers/mtd/chips/cfi_cmdset_0020.c:603:1: error: the frame size of 2080 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
drivers/mtd/chips/cfi_cmdset_0020.c: In function 'cfi_staa_erase_varsize':
drivers/mtd/chips/cfi_cmdset_0020.c:972:1: error: the frame size of 1936 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
drivers/mtd/chips/cfi_cmdset_0001.c: In function 'do_write_buffer':
drivers/mtd/chips/cfi_cmdset_0001.c:1841:1: error: the frame size of 1776 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]

This marks some functions as noinline_for_kasan to keep reduce the
overall stack size.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/mtd/chips/cfi_cmdset_0020.c | 8 ++++----
 include/linux/mtd/map.h             | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 94d3eb42c4d5..8a21e030829c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -244,7 +244,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
 }
 
 
-static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
+static noinline_for_kasan int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
 {
 	map_word status, status_OK;
 	unsigned long timeo;
@@ -728,7 +728,7 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
 }
 
 
-static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+static noinline_for_kasan int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
@@ -1029,7 +1029,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
 	}
 }
 
-static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+static noinline_for_kasan int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
@@ -1175,7 +1175,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	}
 	return 0;
 }
-static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+static noinline_for_kasan int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 3aa56e3104bb..8c2e241f45c7 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -316,7 +316,7 @@ static inline map_word map_word_or(struct map_info *map, map_word val1, map_word
 	return r;
 }
 
-static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
+static noinline_for_kasan int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
 {
 	int i;
 
@@ -328,7 +328,7 @@ static inline int map_word_andequal(struct map_info *map, map_word val1, map_wor
 	return 1;
 }
 
-static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
+static noinline_for_kasan int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
 {
 	int i;
 
@@ -362,7 +362,7 @@ static inline map_word map_word_load(struct map_info *map, const void *ptr)
 	return r;
 }
 
-static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
+static noinline_for_kasan map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
 {
 	int i;
 
@@ -392,7 +392,7 @@ static inline map_word map_word_load_partial(struct map_info *map, map_word orig
 #define MAP_FF_LIMIT 8
 #endif
 
-static inline map_word map_word_ff(struct map_info *map)
+static noinline_for_kasan map_word map_word_ff(struct map_info *map)
 {
 	map_word r;
 	int i;
-- 
2.9.0

^ permalink raw reply related

* [PATCH 4/4] Staging:wilc1000:wilc_spi: Added blank line after function and modified comment style
From: Georgios Emmanouil @ 2017-03-02 17:07 UTC (permalink / raw)
  To: aditya.shankar, ganesh.krishna, gregkh
  Cc: linux-wireless, devel, linux-kernel
In-Reply-To: <1488474379-16101-1-git-send-email-geo.emmnl@gmail.com>

Added blank line after function and modified comment style.

Signed-off-by: Georgios Emmanouil <geo.emmnl@gmail.com>
---
 drivers/staging/wilc1000/wilc_spi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index 4f38922..33c2f7c 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -1128,11 +1128,8 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint)

 	return 1;
 }
-/********************************************
- *
- *      Global spi HIF function table
- *
- ********************************************/
+
+/* Global spi HIF function table */
 static const struct wilc_hif_func wilc_hif_spi = {
 	.hif_init = wilc_spi_init,
 	.hif_deinit = _wilc_spi_deinit,
--
2.1.4

^ permalink raw reply related

* [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
From: Arnd Bergmann @ 2017-03-02 16:38 UTC (permalink / raw)
  To: kasan-dev
  Cc: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov, netdev,
	linux-kernel, linux-media, linux-wireless, kernel-build-reports,
	David S . Miller, Arnd Bergmann
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>

When CONFIG_KASAN is set, we can run into some code that uses incredible
amounts of kernel stack:

drivers/staging/dgnc/dgnc_neo.c:1056:1: error: the frame size of 11112 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size of 94000 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5312 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

This happens when a sanitizer uses stack memory each time an inline function
gets called. This introduces a new annotation for those functions to make
them either 'inline' or 'noinline' dependning on the CONFIG_KASAN symbol.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 include/linux/compiler.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index f8110051188f..56b90897a459 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  */
 #define noinline_for_stack noinline
 
+/*
+ * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
+ * one function gets inlined many times and each instance requires a stack
+ * ckeck.
+ */
+#ifdef CONFIG_KASAN
+#define noinline_for_kasan noinline __maybe_unused
+#else
+#define noinline_for_kasan inline
+#endif
+
 #ifndef __always_inline
 #define __always_inline inline
 #endif
-- 
2.9.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox