1 From e4aa5c0ea49d39fef959fe4bcf5ad728504b5c4f Mon Sep 17 00:00:00 2001
2 From: Martin Schwidefsky <schwidefsky@de.ibm.com>
3 Date: Wed, 3 Apr 2019 09:13:34 +0200
4 Subject: s390/3270: fix lockdep false positive on view->lock
6 [ Upstream commit 5712f3301a12c0c3de9cc423484496b0464f2faf ]
8 The spinlock in the raw3270_view structure is used by con3270, tty3270
9 and fs3270 in different ways. For con3270 the lock can be acquired in
10 irq context, for tty3270 and fs3270 the highest context is bh.
12 Lockdep sees the view->lock as a single class and if the 3270 driver
13 is used for the console the following message is generated:
15 WARNING: inconsistent lock state
16 5.1.0-rc3-05157-g5c168033979d #12 Not tainted
17 --------------------------------
18 inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
19 swapper/0/1 [HC0[0]:SC1[1]:HE1:SE0] takes:
20 (____ptrval____) (&(&view->lock)->rlock){?.-.}, at: tty3270_update+0x7c/0x330
22 Introduce a lockdep subclass for the view lock to distinguish bh from
25 Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
27 Signed-off-by: Sasha Levin <sashal@kernel.org>
29 drivers/s390/char/con3270.c | 2 +-
30 drivers/s390/char/fs3270.c | 3 ++-
31 drivers/s390/char/raw3270.c | 3 ++-
32 drivers/s390/char/raw3270.h | 4 +++-
33 drivers/s390/char/tty3270.c | 3 ++-
34 5 files changed, 10 insertions(+), 5 deletions(-)
36 diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
37 index 285b4006f44bb..5d5e78afde88a 100644
38 --- a/drivers/s390/char/con3270.c
39 +++ b/drivers/s390/char/con3270.c
40 @@ -628,7 +628,7 @@ con3270_init(void)
41 (void (*)(unsigned long)) con3270_read_tasklet,
42 (unsigned long) condev->read);
44 - raw3270_add_view(&condev->view, &con3270_fn, 1);
45 + raw3270_add_view(&condev->view, &con3270_fn, 1, RAW3270_VIEW_LOCK_IRQ);
47 INIT_LIST_HEAD(&condev->freemem);
48 for (i = 0; i < CON3270_STRING_PAGES; i++) {
49 diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
50 index 85eca1cef0630..04a6810a4298c 100644
51 --- a/drivers/s390/char/fs3270.c
52 +++ b/drivers/s390/char/fs3270.c
53 @@ -462,7 +462,8 @@ fs3270_open(struct inode *inode, struct file *filp)
55 init_waitqueue_head(&fp->wait);
56 fp->fs_pid = get_pid(task_pid(current));
57 - rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
58 + rc = raw3270_add_view(&fp->view, &fs3270_fn, minor,
59 + RAW3270_VIEW_LOCK_BH);
61 fs3270_free_view(&fp->view);
63 diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
64 index a2da898ce90fd..1ebf632e327b9 100644
65 --- a/drivers/s390/char/raw3270.c
66 +++ b/drivers/s390/char/raw3270.c
67 @@ -919,7 +919,7 @@ raw3270_deactivate_view(struct raw3270_view *view)
68 * Add view to device with minor "minor".
71 -raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
72 +raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor, int subclass)
76 @@ -941,6 +941,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
77 view->cols = rp->cols;
78 view->ascebc = rp->ascebc;
79 spin_lock_init(&view->lock);
80 + lockdep_set_subclass(&view->lock, subclass);
81 list_add(&view->list, &rp->view_list);
83 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
84 diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
85 index 56519cbb165c7..7577d7d0ad486 100644
86 --- a/drivers/s390/char/raw3270.h
87 +++ b/drivers/s390/char/raw3270.h
88 @@ -149,6 +149,8 @@ struct raw3270_fn {
90 struct list_head list;
92 +#define RAW3270_VIEW_LOCK_IRQ 0
93 +#define RAW3270_VIEW_LOCK_BH 1
96 struct raw3270_fn *fn;
97 @@ -157,7 +159,7 @@ struct raw3270_view {
98 unsigned char *ascebc; /* ascii -> ebcdic table */
101 -int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int);
102 +int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int, int);
103 int raw3270_activate_view(struct raw3270_view *);
104 void raw3270_del_view(struct raw3270_view *);
105 void raw3270_deactivate_view(struct raw3270_view *);
106 diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
107 index 272cb6cd1b2ac..6dd6f9ff7de56 100644
108 --- a/drivers/s390/char/tty3270.c
109 +++ b/drivers/s390/char/tty3270.c
110 @@ -978,7 +978,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
113 rc = raw3270_add_view(&tp->view, &tty3270_fn,
114 - tty->index + RAW3270_FIRSTMINOR);
115 + tty->index + RAW3270_FIRSTMINOR,
116 + RAW3270_VIEW_LOCK_BH);
118 tty3270_free_view(tp);