[RFC] mm/vmscan.c: avoid possible long latency caused by too_many_isolated()

2021-04-15 Thread zhengjun . xing
From: Zhengjun Xing 

In the system with very few file pages, it is easy to reproduce
"nr_isolated_file > nr_inactive_file",  then too_many_isolated return true,
shrink_inactive_list enter "msleep(100)", the long latency will happen.
The test case to reproduce it is very simple, allocate a lot of huge pages
(near the DRAM size), then do free, repeat the same operation many times.
There is a 3/10 rate to reproduce the issue. In the test, sc-> gfp_mask
is 0x342cca ("_GFP_IO" and "__GFP_FS" is masked),it is more easy to enter
“inactive >>=3”, then “isolated > inactive” will easy to be true.

So I  have a proposal to set a threshold number for the total file pages
to ignore the system with very few file pages, and then bypass the 100ms
sleep. It is hard to set a perfect number for the threshold, so I
just give an example of "256" for it, need more inputs for it.

Signed-off-by: Zhengjun Xing 
---
 mm/vmscan.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 562e87cbd7a1..a1926463455c 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -168,6 +168,7 @@ struct scan_control {
  * From 0 .. 200.  Higher means more swappy.
  */
 int vm_swappiness = 60;
+int lru_list_threshold = SWAP_CLUSTER_MAX << 3;
 
 static void set_task_reclaim_state(struct task_struct *task,
   struct reclaim_state *rs)
@@ -1785,7 +1786,7 @@ int isolate_lru_page(struct page *page)
 static int too_many_isolated(struct pglist_data *pgdat, int file,
struct scan_control *sc)
 {
-   unsigned long inactive, isolated;
+   unsigned long inactive, isolated, active, nr_lru_pages;
 
if (current_is_kswapd())
return 0;
@@ -1796,11 +1797,13 @@ static int too_many_isolated(struct pglist_data *pgdat, 
int file,
if (file) {
inactive = node_page_state(pgdat, NR_INACTIVE_FILE);
isolated = node_page_state(pgdat, NR_ISOLATED_FILE);
+   active = node_page_state(pgdat, NR_ACTIVE_FILE);
} else {
inactive = node_page_state(pgdat, NR_INACTIVE_ANON);
isolated = node_page_state(pgdat, NR_ISOLATED_ANON);
+   active = node_page_state(pgdat, NR_ACTIVE_ANON);
}
-
+   nr_lru_pages = inactive + active;
/*
 * GFP_NOIO/GFP_NOFS callers are allowed to isolate more pages, so they
 * won't get blocked by normal direct-reclaimers, forming a circular
@@ -1809,6 +1812,10 @@ static int too_many_isolated(struct pglist_data *pgdat, 
int file,
if ((sc->gfp_mask & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS))
inactive >>= 3;
 
+   if (isolated > inactive)
+   if (nr_lru_pages < lru_list_threshold)
+   return 0;
+
return isolated > inactive;
 }
 
-- 
2.17.1



[PATCH v2] tracing: fix "gfp_t" format for synthetic events

2019-10-17 Thread Zhengjun Xing
In the format of synthetic events, the "gfp_t" is shown as "signed:1",
but in fact the "gfp_t" is "unsigned", should be shown as "signed:0".

The issue can be reproduced by the following commands:

echo 'memlatency u64 lat; unsigned int order; gfp_t gfp_flags; int migratetype' 
> /sys/kernel/debug/tracing/synthetic_events
cat  /sys/kernel/debug/tracing/events/synthetic/memlatency/format

name: memlatency
ID: 2233
format:
field:unsigned short common_type;   offset:0;   size:2; 
signed:0;
field:unsigned char common_flags;   offset:2;   size:1; 
signed:0;
field:unsigned char common_preempt_count;   offset:3;   size:1; 
signed:0;
field:int common_pid;   offset:4;   size:4; signed:1;

field:u64 lat;  offset:8;   size:8; signed:0;
field:unsigned int order;   offset:16;  size:4; signed:0;
field:gfp_t gfp_flags;  offset:24;  size:4; signed:1;
field:int migratetype;  offset:32;  size:4; signed:1;

print fmt: "lat=%llu, order=%u, gfp_flags=%x, migratetype=%d", REC->lat, 
REC->order, REC->gfp_flags, REC->migratetype

Signed-off-by: Zhengjun Xing 
---
 kernel/trace/trace_events_hist.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 57648c5aa679..7482a1466ebf 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -679,6 +679,8 @@ static bool synth_field_signed(char *type)
 {
if (str_has_prefix(type, "u"))
return false;
+   if (strcmp(type, "gfp_t") == 0)
+   return false;
 
return true;
 }
-- 
2.17.1



[PATCH] tracing: fix "gfp_t" format for synthetic events

2019-10-17 Thread Zhengjun Xing
In the format of synthetic events, the "gfp_t" is shown as "signed:1",
but in fact the "gfp_t" is "unsigned", should be shown as "signed:0".
The offset should be increased by the real size of each field, rather
than by the size of "u64".

The issue can be reproduced by the following commands:

echo 'memlatency u64 lat; unsigned int order; gfp_t gfp_flags; int migratetype' 
> /sys/kernel/debug/tracing/synthetic_events
cat  /sys/kernel/debug/tracing/events/synthetic/memlatency/format

name: memlatency
ID: 2233
format:
field:unsigned short common_type;   offset:0;   size:2; 
signed:0;
field:unsigned char common_flags;   offset:2;   size:1; 
signed:0;
field:unsigned char common_preempt_count;   offset:3;   size:1; 
signed:0;
field:int common_pid;   offset:4;   size:4; signed:1;

field:u64 lat;  offset:8;   size:8; signed:0;
field:unsigned int order;   offset:16;  size:4; signed:0;
field:gfp_t gfp_flags;  offset:24;  size:4; signed:1;
field:int migratetype;  offset:32;  size:4; signed:1;

print fmt: "lat=%llu, order=%u, gfp_flags=%x, migratetype=%d", REC->lat, 
REC->order, REC->gfp_flags, REC->migratetype

Signed-off-by: Zhengjun Xing 
---
 kernel/trace/trace_events_hist.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 57648c5aa679..7d70321d03b1 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -665,7 +665,7 @@ static int synth_event_define_fields(struct 
trace_event_call *call)
offset += STR_VAR_LEN_MAX;
n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
} else {
-   offset += sizeof(u64);
+   offset += size;
n_u64++;
}
}
@@ -679,6 +679,8 @@ static bool synth_field_signed(char *type)
 {
if (str_has_prefix(type, "u"))
return false;
+   if (strcmp(type, "gfp_t") == 0)
+   return false;
 
return true;
 }
-- 
2.17.1



[PATCH v3] trace:Add "gfp_t" support in synthetic_events

2019-07-11 Thread Zhengjun Xing
Add "gfp_t" support in synthetic_events, then the "gfp_t" type
parameter in some functions can be traced.

Prints the gfp flags as hex in addition to the human-readable flag
string.  Example output:

  whoopsie-630 [000] ...1 78.969452: testevent: bar=b20 (GFP_ATOMIC|__GFP_ZERO)
rcuc/0-11  [000] ...1 81.097555: testevent: bar=a20 (GFP_ATOMIC)
rcuc/0-11  [000] ...1 81.583123: testevent: bar=a20 (GFP_ATOMIC)

Signed-off-by: Tom Zanussi 
Signed-off-by: Zhengjun Xing 
---
 kernel/trace/trace_events_hist.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index ca6b0dff60c5..30f0f32aca62 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -13,6 +13,10 @@
 #include 
 #include 
 
+/* for gfp flag names */
+#include 
+#include 
+
 #include "tracing_map.h"
 #include "trace.h"
 #include "trace_dynevent.h"
@@ -752,6 +756,8 @@ static int synth_field_size(char *type)
size = sizeof(unsigned long);
else if (strcmp(type, "pid_t") == 0)
size = sizeof(pid_t);
+   else if (strcmp(type, "gfp_t") == 0)
+   size = sizeof(gfp_t);
else if (synth_field_is_string(type))
size = synth_field_string_size(type);
 
@@ -792,6 +798,8 @@ static const char *synth_field_fmt(char *type)
fmt = "%lu";
else if (strcmp(type, "pid_t") == 0)
fmt = "%d";
+   else if (strcmp(type, "gfp_t") == 0)
+   fmt = "%x";
else if (synth_field_is_string(type))
fmt = "%s";
 
@@ -834,9 +842,20 @@ static enum print_line_t print_synth_event(struct 
trace_iterator *iter,
 i == se->n_fields - 1 ? "" : " ");
n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
} else {
+   struct trace_print_flags __flags[] = {
+   __def_gfpflag_names, {-1, NULL} };
+
trace_seq_printf(s, print_fmt, se->fields[i]->name,
 entry->fields[n_u64],
 i == se->n_fields - 1 ? "" : " ");
+
+   if (strcmp(se->fields[i]->type, "gfp_t") == 0) {
+   trace_seq_puts(s, " (");
+   trace_print_flags_seq(s, "|",
+ entry->fields[n_u64],
+ __flags);
+   trace_seq_putc(s, ')');
+   }
n_u64++;
}
}
-- 
2.14.1



[PATCH v2] tracing: Add verbose gfp_flag printing to synthetic events

2019-07-11 Thread Zhengjun Xing
Add on top of 'trace:add "gfp_t" support in synthetic_events'.

Prints the gfp flags as hex in addition to the human-readable flag
string.  Example output:

  whoopsie-630 [000] ...1 78.969452: testevent: bar=b20 (GFP_ATOMIC|__GFP_ZERO)
rcuc/0-11  [000] ...1 81.097555: testevent: bar=a20 (GFP_ATOMIC)
rcuc/0-11  [000] ...1 81.583123: testevent: bar=a20 (GFP_ATOMIC)

Signed-off-by: Tom Zanussi 
Signed-off-by: Zhengjun Xing 
---
 kernel/trace/trace_events_hist.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index ca6b0dff60c5..938ef3f54c5c 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -13,6 +13,10 @@
 #include 
 #include 
 
+/* for gfp flag names */
+#include 
+#include 
+
 #include "tracing_map.h"
 #include "trace.h"
 #include "trace_dynevent.h"
@@ -752,6 +756,8 @@ static int synth_field_size(char *type)
size = sizeof(unsigned long);
else if (strcmp(type, "pid_t") == 0)
size = sizeof(pid_t);
+   else if (strcmp(type, "gfp_t") == 0)
+   size = sizeof(gfp_t);
else if (synth_field_is_string(type))
size = synth_field_string_size(type);
 
@@ -792,6 +798,8 @@ static const char *synth_field_fmt(char *type)
fmt = "%lu";
else if (strcmp(type, "pid_t") == 0)
fmt = "%d";
+   else if (strcmp(type, "gfp_t") == 0)
+   fmt = "%x";
else if (synth_field_is_string(type))
fmt = "%s";
 
@@ -834,9 +838,20 @@ static enum print_line_t print_synth_event(struct 
trace_iterator *iter,
 i == se->n_fields - 1 ? "" : " ");
n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
} else {
+   struct trace_print_flags __flags[] = {
+   __def_gfpflag_names, {-1, NULL} };
+
trace_seq_printf(s, print_fmt, se->fields[i]->name,
 entry->fields[n_u64],
 i == se->n_fields - 1 ? "" : " ");
+
+   if (strcmp(se->fields[i]->type, "gfp_t") == 0) {
+   trace_seq_puts(s, " (");
+   trace_print_flags_seq(s, "|",
+ entry->fields[n_u64],
+ __flags);
+   trace_seq_putc(s, ')');
+   }
n_u64++;
}
}
-- 
2.14.1



[PATCH] trace:add "gfp_t" support in synthetic_events

2019-07-03 Thread Zhengjun Xing
Add "gfp_t" support in synthetic_events, then the "gfp_t" type
parameter in some functions can be traced.

Signed-off-by: Zhengjun Xing 
---
 kernel/trace/trace_events_hist.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index ca6b0dff60c5..0d3ab01b7cb5 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -752,6 +752,8 @@ static int synth_field_size(char *type)
size = sizeof(unsigned long);
else if (strcmp(type, "pid_t") == 0)
size = sizeof(pid_t);
+   else if (strcmp(type, "gfp_t") == 0)
+   size = sizeof(gfp_t);
else if (synth_field_is_string(type))
size = synth_field_string_size(type);
 
@@ -792,6 +794,8 @@ static const char *synth_field_fmt(char *type)
fmt = "%lu";
else if (strcmp(type, "pid_t") == 0)
fmt = "%d";
+   else if (strcmp(type, "gfp_t") == 0)
+   fmt = "%u";
else if (synth_field_is_string(type))
fmt = "%s";
 
-- 
2.14.1



[PATCH] USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw

2018-03-20 Thread Zhengjun Xing
USB3 hubs don't support global suspend.

USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective
suspend and resume, they do not support global suspend/resume where the
hub downstream facing ports states are not affected.

When system enters hibernation it first enters freeze process where only
the root hub enters suspend, usb_port_suspend() is not called for other
devices, and suspend status flags are not set for them. Other devices are
expected to suspend globally. Some external USB3 hubs will suspend the
downstream facing port at global suspend. These devices won't be resumed
at thaw as the suspend status flag is not set.

A USB3 removable hard disk connected through a USB3 hub that won't resume
at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71”
error, and needs a 60 seconds timeout which causing system hang for 60s
before the USB host reset the port for the USB3 removable hard disk to
recover.

Fix this by always calling usb_port_suspend() during freeze for USB3
devices.

Signed-off-by: Zhengjun Xing <zhengjun.x...@linux.intel.com>
---
 drivers/usb/core/generic.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 83c14dda6300..bc8242bc4564 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -210,8 +210,13 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
if (!udev->parent)
rc = hcd_bus_suspend(udev, msg);
 
-   /* Non-root devices don't need to do anything for FREEZE or PRETHAW */
-   else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+   /*
+* Non-root USB2 devices don't need to do anything for FREEZE
+* or PRETHAW. USB3 devices don't support global suspend and
+* needs to be selectively suspended.
+*/
+   else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+&& (udev->speed < USB_SPEED_SUPER))
rc = 0;
else
rc = usb_port_suspend(udev, msg);
-- 
2.11.0



[PATCH] USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw

2018-03-20 Thread Zhengjun Xing
USB3 hubs don't support global suspend.

USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective
suspend and resume, they do not support global suspend/resume where the
hub downstream facing ports states are not affected.

When system enters hibernation it first enters freeze process where only
the root hub enters suspend, usb_port_suspend() is not called for other
devices, and suspend status flags are not set for them. Other devices are
expected to suspend globally. Some external USB3 hubs will suspend the
downstream facing port at global suspend. These devices won't be resumed
at thaw as the suspend status flag is not set.

A USB3 removable hard disk connected through a USB3 hub that won't resume
at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71”
error, and needs a 60 seconds timeout which causing system hang for 60s
before the USB host reset the port for the USB3 removable hard disk to
recover.

Fix this by always calling usb_port_suspend() during freeze for USB3
devices.

Signed-off-by: Zhengjun Xing 
---
 drivers/usb/core/generic.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 83c14dda6300..bc8242bc4564 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -210,8 +210,13 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
if (!udev->parent)
rc = hcd_bus_suspend(udev, msg);
 
-   /* Non-root devices don't need to do anything for FREEZE or PRETHAW */
-   else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+   /*
+* Non-root USB2 devices don't need to do anything for FREEZE
+* or PRETHAW. USB3 devices don't support global suspend and
+* needs to be selectively suspended.
+*/
+   else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
+&& (udev->speed < USB_SPEED_SUPER))
rc = 0;
else
rc = usb_port_suspend(udev, msg);
-- 
2.11.0



[PATCH] xhci:Fix NULL pointer in xhci debugfs

2018-01-18 Thread Zhengjun Xing
Commit dde634057da7 ("xhci: Fix use-after-free in xhci debugfs") causes a
null pointer dereference while fixing xhci-debugfs usage of ring pointers
that were freed during hibernate.

The fix passed addresses to ring pointers instead, but forgot to do this
change for the xhci_ring_trb_show function.

The address of the ring pointer passed to xhci-debugfs was of a temporary
ring pointer "new_ring" instead of the actual ring "ring" pointer. The
temporary new_ring pointer will be set to NULL later causing the NULL
pointer dereference.

This issue was seen when reading xhci related files in debugfs:

cat /sys/kernel/debug/usb/xhci/*/devices/*/ep*/trbs

[  184.604861] BUG: unable to handle kernel NULL pointer dereference at (null)
[  184.613776] IP: xhci_ring_trb_show+0x3a/0x890
[  184.618733] PGD 264193067 P4D 264193067 PUD 263238067 PMD 0
[  184.625184] Oops:  [#1] SMP
[  184.726410] RIP: 0010:xhci_ring_trb_show+0x3a/0x890
[  184.731944] RSP: 0018:ba8243c0fd90 EFLAGS: 00010246
[  184.737880] RAX:  RBX:  RCX: 000295d6
[  184.746020] RDX: 000295d5 RSI: 0001 RDI: 971a6418d400
[  184.754121] RBP:  R08:  R09: 
[  184.76] R10: 971a64c98a80 R11: 971a62a00e40 R12: 971a62a85500
[  184.770325] R13: 0002 R14: 971a6418d400 R15: 971a6418d400
[  184.778448] FS:  7fe725a79700() GS:971a6ec0() 
knlGS:
[  184.787644] CS:  0010 DS:  ES:  CR0: 80050033
[  184.794168] CR2:  CR3: 00025f365005 CR4: 003606f0
[  184.802318] Call Trace:
[  184.805094]  ? seq_read+0x281/0x3b0
[  184.809068]  seq_read+0xeb/0x3b0
[  184.812735]  full_proxy_read+0x4d/0x70
[  184.817007]  __vfs_read+0x23/0x120
[  184.820870]  vfs_read+0x91/0x130
[  184.824538]  SyS_read+0x42/0x90
[  184.828106]  entry_SYSCALL_64_fastpath+0x1a/0x7d

Fixes: dde634057da7 ("xhci: Fix use-after-free in xhci debugfs")
Signed-off-by: Zhengjun Xing <zhengjun.x...@linux.intel.com>
---
 drivers/usb/host/xhci-debugfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index e26e685d8a57..5851052d4668 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -211,7 +211,7 @@ static void xhci_ring_dump_segment(struct seq_file *s,
 static int xhci_ring_trb_show(struct seq_file *s, void *unused)
 {
int i;
-   struct xhci_ring*ring = s->private;
+   struct xhci_ring*ring = *(struct xhci_ring **)s->private;
struct xhci_segment *seg = ring->first_seg;
 
for (i = 0; i < ring->num_segs; i++) {
@@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
 
snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
epriv->root = xhci_debugfs_create_ring_dir(xhci,
-  >eps[ep_index].new_ring,
+  >eps[ep_index].ring,
   epriv->name,
   spriv->root);
spriv->eps[ep_index] = epriv;
-- 
2.11.0



[PATCH] xhci:Fix NULL pointer in xhci debugfs

2018-01-18 Thread Zhengjun Xing
Commit dde634057da7 ("xhci: Fix use-after-free in xhci debugfs") causes a
null pointer dereference while fixing xhci-debugfs usage of ring pointers
that were freed during hibernate.

The fix passed addresses to ring pointers instead, but forgot to do this
change for the xhci_ring_trb_show function.

The address of the ring pointer passed to xhci-debugfs was of a temporary
ring pointer "new_ring" instead of the actual ring "ring" pointer. The
temporary new_ring pointer will be set to NULL later causing the NULL
pointer dereference.

This issue was seen when reading xhci related files in debugfs:

cat /sys/kernel/debug/usb/xhci/*/devices/*/ep*/trbs

[  184.604861] BUG: unable to handle kernel NULL pointer dereference at (null)
[  184.613776] IP: xhci_ring_trb_show+0x3a/0x890
[  184.618733] PGD 264193067 P4D 264193067 PUD 263238067 PMD 0
[  184.625184] Oops:  [#1] SMP
[  184.726410] RIP: 0010:xhci_ring_trb_show+0x3a/0x890
[  184.731944] RSP: 0018:ba8243c0fd90 EFLAGS: 00010246
[  184.737880] RAX:  RBX:  RCX: 000295d6
[  184.746020] RDX: 000295d5 RSI: 0001 RDI: 971a6418d400
[  184.754121] RBP:  R08:  R09: 
[  184.76] R10: 971a64c98a80 R11: 971a62a00e40 R12: 971a62a85500
[  184.770325] R13: 0002 R14: 971a6418d400 R15: 971a6418d400
[  184.778448] FS:  7fe725a79700() GS:971a6ec0() 
knlGS:
[  184.787644] CS:  0010 DS:  ES:  CR0: 80050033
[  184.794168] CR2:  CR3: 00025f365005 CR4: 003606f0
[  184.802318] Call Trace:
[  184.805094]  ? seq_read+0x281/0x3b0
[  184.809068]  seq_read+0xeb/0x3b0
[  184.812735]  full_proxy_read+0x4d/0x70
[  184.817007]  __vfs_read+0x23/0x120
[  184.820870]  vfs_read+0x91/0x130
[  184.824538]  SyS_read+0x42/0x90
[  184.828106]  entry_SYSCALL_64_fastpath+0x1a/0x7d

Fixes: dde634057da7 ("xhci: Fix use-after-free in xhci debugfs")
Signed-off-by: Zhengjun Xing 
---
 drivers/usb/host/xhci-debugfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index e26e685d8a57..5851052d4668 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -211,7 +211,7 @@ static void xhci_ring_dump_segment(struct seq_file *s,
 static int xhci_ring_trb_show(struct seq_file *s, void *unused)
 {
int i;
-   struct xhci_ring*ring = s->private;
+   struct xhci_ring*ring = *(struct xhci_ring **)s->private;
struct xhci_segment *seg = ring->first_seg;
 
for (i = 0; i < ring->num_segs; i++) {
@@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
 
snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
epriv->root = xhci_debugfs_create_ring_dir(xhci,
-  >eps[ep_index].new_ring,
+  >eps[ep_index].ring,
   epriv->name,
   spriv->root);
spriv->eps[ep_index] = epriv;
-- 
2.11.0



[PATCH] tracing: Add *iter check for NULL

2016-06-01 Thread zhengjun . xing
From: xingzhen 

3debb0a9ddb adding a "__used" to the variable in the
__trace_printk_fmt section. Sometimes it will cause
*iter to be NULL, then strcmp in lookup_format and
strcpy in hold_module_trace_bprintk_format will panic.

Signed-off-by: xingzhen 
---
 kernel/trace/trace_printk.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index f96f038..82ecfb5 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -55,6 +55,8 @@ void hold_module_trace_bprintk_format(const char **start, 
const char **end)
 
mutex_lock(_mutex);
for (iter = start; iter < end; iter++) {
+   if (!*iter)
+   goto err;
struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
if (tb_fmt) {
*iter = tb_fmt->fmt;
@@ -75,6 +77,7 @@ void hold_module_trace_bprintk_format(const char **start, 
const char **end)
*iter = fmt;
 
}
+err:
mutex_unlock(_mutex);
 }
 
-- 
1.9.1



[PATCH] tracing: Add *iter check for NULL

2016-06-01 Thread zhengjun . xing
From: xingzhen 

3debb0a9ddb adding a "__used" to the variable in the
__trace_printk_fmt section. Sometimes it will cause
*iter to be NULL, then strcmp in lookup_format and
strcpy in hold_module_trace_bprintk_format will panic.

Signed-off-by: xingzhen 
---
 kernel/trace/trace_printk.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index f96f038..82ecfb5 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -55,6 +55,8 @@ void hold_module_trace_bprintk_format(const char **start, 
const char **end)
 
mutex_lock(_mutex);
for (iter = start; iter < end; iter++) {
+   if (!*iter)
+   goto err;
struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
if (tb_fmt) {
*iter = tb_fmt->fmt;
@@ -75,6 +77,7 @@ void hold_module_trace_bprintk_format(const char **start, 
const char **end)
*iter = fmt;
 
}
+err:
mutex_unlock(_mutex);
 }
 
-- 
1.9.1