aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/workqueue.txt40
-rw-r--r--drivers/i2c/busses/i2c-i801.c5
-rw-r--r--drivers/i2c/busses/i2c-parport.c27
-rw-r--r--include/linux/pci_ids.h4
-rw-r--r--kernel/workqueue.c8
-rw-r--r--lib/xz/xz_dec_lzma2.c6
6 files changed, 69 insertions, 21 deletions
diff --git a/Documentation/workqueue.txt b/Documentation/workqueue.txt
index 01c513fac40e..a0b577de918f 100644
--- a/Documentation/workqueue.txt
+++ b/Documentation/workqueue.txt
@@ -12,6 +12,7 @@ CONTENTS
124. Application Programming Interface (API) 124. Application Programming Interface (API)
135. Example Execution Scenarios 135. Example Execution Scenarios
146. Guidelines 146. Guidelines
157. Debugging
15 16
16 17
171. Introduction 181. Introduction
@@ -379,3 +380,42 @@ If q1 has WQ_CPU_INTENSIVE set,
379* Unless work items are expected to consume a huge amount of CPU 380* Unless work items are expected to consume a huge amount of CPU
380 cycles, using a bound wq is usually beneficial due to the increased 381 cycles, using a bound wq is usually beneficial due to the increased
381 level of locality in wq operations and work item execution. 382 level of locality in wq operations and work item execution.
383
384
3857. Debugging
386
387Because the work functions are executed by generic worker threads
388there are a few tricks needed to shed some light on misbehaving
389workqueue users.
390
391Worker threads show up in the process list as:
392
393root 5671 0.0 0.0 0 0 ? S 12:07 0:00 [kworker/0:1]
394root 5672 0.0 0.0 0 0 ? S 12:07 0:00 [kworker/1:2]
395root 5673 0.0 0.0 0 0 ? S 12:12 0:00 [kworker/0:0]
396root 5674 0.0 0.0 0 0 ? S 12:13 0:00 [kworker/1:0]
397
398If kworkers are going crazy (using too much cpu), there are two types
399of possible problems:
400
401 1. Something beeing scheduled in rapid succession
402 2. A single work item that consumes lots of cpu cycles
403
404The first one can be tracked using tracing:
405
406 $ echo workqueue:workqueue_queue_work > /sys/kernel/debug/tracing/set_event
407 $ cat /sys/kernel/debug/tracing/trace_pipe > out.txt
408 (wait a few secs)
409 ^C
410
411If something is busy looping on work queueing, it would be dominating
412the output and the offender can be determined with the work item
413function.
414
415For the second type of problems it should be possible to just check
416the stack trace of the offending worker thread.
417
418 $ cat /proc/THE_OFFENDING_KWORKER/stack
419
420The work item's function should be trivially visible in the stack
421trace.
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 72c0415f6f94..455e909bc768 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -134,10 +134,15 @@
134 SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ 134 SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \
135 SMBHSTSTS_INTR) 135 SMBHSTSTS_INTR)
136 136
137/* Older devices have their ID defined in <linux/pci_ids.h> */
138#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
139#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
137/* Patsburg also has three 'Integrated Device Function' SMBus controllers */ 140/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
138#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 141#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70
139#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 142#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
140#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 143#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72
144#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
145#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
141 146
142struct i801_priv { 147struct i801_priv {
143 struct i2c_adapter adapter; 148 struct i2c_adapter adapter;
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 0eb1515541e7..2dbba163b102 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -1,7 +1,7 @@
1/* ------------------------------------------------------------------------ * 1/* ------------------------------------------------------------------------ *
2 * i2c-parport.c I2C bus over parallel port * 2 * i2c-parport.c I2C bus over parallel port *
3 * ------------------------------------------------------------------------ * 3 * ------------------------------------------------------------------------ *
4 Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> 4 Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org>
5 5
6 Based on older i2c-philips-par.c driver 6 Based on older i2c-philips-par.c driver
7 Copyright (C) 1995-2000 Simon G. Vogl 7 Copyright (C) 1995-2000 Simon G. Vogl
@@ -33,6 +33,8 @@
33#include <linux/i2c-algo-bit.h> 33#include <linux/i2c-algo-bit.h>
34#include <linux/i2c-smbus.h> 34#include <linux/i2c-smbus.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/list.h>
37#include <linux/mutex.h>
36#include "i2c-parport.h" 38#include "i2c-parport.h"
37 39
38/* ----- Device list ------------------------------------------------------ */ 40/* ----- Device list ------------------------------------------------------ */
@@ -43,10 +45,11 @@ struct i2c_par {
43 struct i2c_algo_bit_data algo_data; 45 struct i2c_algo_bit_data algo_data;
44 struct i2c_smbus_alert_setup alert_data; 46 struct i2c_smbus_alert_setup alert_data;
45 struct i2c_client *ara; 47 struct i2c_client *ara;
46 struct i2c_par *next; 48 struct list_head node;
47}; 49};
48 50
49static struct i2c_par *adapter_list; 51static LIST_HEAD(adapter_list);
52static DEFINE_MUTEX(adapter_list_lock);
50 53
51/* ----- Low-level parallel port access ----------------------------------- */ 54/* ----- Low-level parallel port access ----------------------------------- */
52 55
@@ -228,8 +231,9 @@ static void i2c_parport_attach (struct parport *port)
228 } 231 }
229 232
230 /* Add the new adapter to the list */ 233 /* Add the new adapter to the list */
231 adapter->next = adapter_list; 234 mutex_lock(&adapter_list_lock);
232 adapter_list = adapter; 235 list_add_tail(&adapter->node, &adapter_list);
236 mutex_unlock(&adapter_list_lock);
233 return; 237 return;
234 238
235ERROR1: 239ERROR1:
@@ -241,11 +245,11 @@ ERROR0:
241 245
242static void i2c_parport_detach (struct parport *port) 246static void i2c_parport_detach (struct parport *port)
243{ 247{
244 struct i2c_par *adapter, *prev; 248 struct i2c_par *adapter, *_n;
245 249
246 /* Walk the list */ 250 /* Walk the list */
247 for (prev = NULL, adapter = adapter_list; adapter; 251 mutex_lock(&adapter_list_lock);
248 prev = adapter, adapter = adapter->next) { 252 list_for_each_entry_safe(adapter, _n, &adapter_list, node) {
249 if (adapter->pdev->port == port) { 253 if (adapter->pdev->port == port) {
250 if (adapter->ara) { 254 if (adapter->ara) {
251 parport_disable_irq(port); 255 parport_disable_irq(port);
@@ -259,14 +263,11 @@ static void i2c_parport_detach (struct parport *port)
259 263
260 parport_release(adapter->pdev); 264 parport_release(adapter->pdev);
261 parport_unregister_device(adapter->pdev); 265 parport_unregister_device(adapter->pdev);
262 if (prev) 266 list_del(&adapter->node);
263 prev->next = adapter->next;
264 else
265 adapter_list = adapter->next;
266 kfree(adapter); 267 kfree(adapter);
267 return;
268 } 268 }
269 } 269 }
270 mutex_unlock(&adapter_list_lock);
270} 271}
271 272
272static struct parport_driver i2c_parport_driver = { 273static struct parport_driver i2c_parport_driver = {
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 4e2c9150a785..8abe8d78c4bf 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2477,15 +2477,12 @@
2477#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 2477#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21
2478#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 2478#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30
2479#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 2479#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38
2480#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
2481#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 2480#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41
2482#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f 2481#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f
2483#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
2484#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 2482#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40
2485#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 2483#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41
2486#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 2484#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310
2487#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f 2485#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f
2488#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
2489#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 2486#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
2490#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 2487#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
2491#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 2488#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
@@ -2696,7 +2693,6 @@
2696#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 2693#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60
2697#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00 2694#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00
2698#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f 2695#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f
2699#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
2700#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f 2696#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
2701#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 2697#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0
2702#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 2698#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 8859a41806dd..e3378e8d3a5c 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1291,8 +1291,14 @@ __acquires(&gcwq->lock)
1291 return true; 1291 return true;
1292 spin_unlock_irq(&gcwq->lock); 1292 spin_unlock_irq(&gcwq->lock);
1293 1293
1294 /* CPU has come up in between, retry migration */ 1294 /*
1295 * We've raced with CPU hot[un]plug. Give it a breather
1296 * and retry migration. cond_resched() is required here;
1297 * otherwise, we might deadlock against cpu_stop trying to
1298 * bring down the CPU on non-preemptive kernel.
1299 */
1295 cpu_relax(); 1300 cpu_relax();
1301 cond_resched();
1296 } 1302 }
1297} 1303}
1298 1304
diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c
index ea5fa4fe9d67..a6cdc969ea42 100644
--- a/lib/xz/xz_dec_lzma2.c
+++ b/lib/xz/xz_dec_lzma2.c
@@ -969,6 +969,9 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
969 */ 969 */
970 tmp = b->in[b->in_pos++]; 970 tmp = b->in[b->in_pos++];
971 971
972 if (tmp == 0x00)
973 return XZ_STREAM_END;
974
972 if (tmp >= 0xE0 || tmp == 0x01) { 975 if (tmp >= 0xE0 || tmp == 0x01) {
973 s->lzma2.need_props = true; 976 s->lzma2.need_props = true;
974 s->lzma2.need_dict_reset = false; 977 s->lzma2.need_dict_reset = false;
@@ -1001,9 +1004,6 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
1001 lzma_reset(s); 1004 lzma_reset(s);
1002 } 1005 }
1003 } else { 1006 } else {
1004 if (tmp == 0x00)
1005 return XZ_STREAM_END;
1006
1007 if (tmp > 0x02) 1007 if (tmp > 0x02)
1008 return XZ_DATA_ERROR; 1008 return XZ_DATA_ERROR;
1009 1009