aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Herbert <tom@quantonium.net>2017-10-20 19:40:43 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-24 21:37:11 -0400
commit829385f08ae99740276cbd46c9db29764c519211 (patch)
treea95d023c7d12186bd605660c93841df05086e65c
parent864f5af3a3525f588391cd230cb8129ad758708e (diff)
strparser: Use delayed work instead of timer for msg timeout
Sock lock may be taken in the message timer function which is a problem since timers run in BH. Instead of timers use delayed_work. Reported-by: Eric Dumazet <eric.dumazet@gmail.com> Fixes: bbb03029a899 ("strparser: Generalize strparser") Signed-off-by: Tom Herbert <tom@quantonium.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/strparser.h3
-rw-r--r--net/strparser/strparser.c17
2 files changed, 9 insertions, 11 deletions
diff --git a/include/net/strparser.h b/include/net/strparser.h
index 7dc131d62ad5..d96b59f45eba 100644
--- a/include/net/strparser.h
+++ b/include/net/strparser.h
@@ -74,10 +74,9 @@ struct strparser {
74 u32 unrecov_intr : 1; 74 u32 unrecov_intr : 1;
75 75
76 struct sk_buff **skb_nextp; 76 struct sk_buff **skb_nextp;
77 struct timer_list msg_timer;
78 struct sk_buff *skb_head; 77 struct sk_buff *skb_head;
79 unsigned int need_bytes; 78 unsigned int need_bytes;
80 struct delayed_work delayed_work; 79 struct delayed_work msg_timer_work;
81 struct work_struct work; 80 struct work_struct work;
82 struct strp_stats stats; 81 struct strp_stats stats;
83 struct strp_callbacks cb; 82 struct strp_callbacks cb;
diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c
index d4ea46a5f233..c5fda15ba319 100644
--- a/net/strparser/strparser.c
+++ b/net/strparser/strparser.c
@@ -49,7 +49,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
49{ 49{
50 /* Unrecoverable error in receive */ 50 /* Unrecoverable error in receive */
51 51
52 del_timer(&strp->msg_timer); 52 cancel_delayed_work(&strp->msg_timer_work);
53 53
54 if (strp->stopped) 54 if (strp->stopped)
55 return; 55 return;
@@ -68,7 +68,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
68static void strp_start_timer(struct strparser *strp, long timeo) 68static void strp_start_timer(struct strparser *strp, long timeo)
69{ 69{
70 if (timeo) 70 if (timeo)
71 mod_timer(&strp->msg_timer, timeo); 71 mod_delayed_work(strp_wq, &strp->msg_timer_work, timeo);
72} 72}
73 73
74/* Lower lock held */ 74/* Lower lock held */
@@ -319,7 +319,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
319 eaten += (cand_len - extra); 319 eaten += (cand_len - extra);
320 320
321 /* Hurray, we have a new message! */ 321 /* Hurray, we have a new message! */
322 del_timer(&strp->msg_timer); 322 cancel_delayed_work(&strp->msg_timer_work);
323 strp->skb_head = NULL; 323 strp->skb_head = NULL;
324 STRP_STATS_INCR(strp->stats.msgs); 324 STRP_STATS_INCR(strp->stats.msgs);
325 325
@@ -450,9 +450,10 @@ static void strp_work(struct work_struct *w)
450 do_strp_work(container_of(w, struct strparser, work)); 450 do_strp_work(container_of(w, struct strparser, work));
451} 451}
452 452
453static void strp_msg_timeout(unsigned long arg) 453static void strp_msg_timeout(struct work_struct *w)
454{ 454{
455 struct strparser *strp = (struct strparser *)arg; 455 struct strparser *strp = container_of(w, struct strparser,
456 msg_timer_work.work);
456 457
457 /* Message assembly timed out */ 458 /* Message assembly timed out */
458 STRP_STATS_INCR(strp->stats.msg_timeouts); 459 STRP_STATS_INCR(strp->stats.msg_timeouts);
@@ -505,9 +506,7 @@ int strp_init(struct strparser *strp, struct sock *sk,
505 strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done; 506 strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done;
506 strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp; 507 strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp;
507 508
508 setup_timer(&strp->msg_timer, strp_msg_timeout, 509 INIT_DELAYED_WORK(&strp->msg_timer_work, strp_msg_timeout);
509 (unsigned long)strp);
510
511 INIT_WORK(&strp->work, strp_work); 510 INIT_WORK(&strp->work, strp_work);
512 511
513 return 0; 512 return 0;
@@ -532,7 +531,7 @@ void strp_done(struct strparser *strp)
532{ 531{
533 WARN_ON(!strp->stopped); 532 WARN_ON(!strp->stopped);
534 533
535 del_timer_sync(&strp->msg_timer); 534 cancel_delayed_work_sync(&strp->msg_timer_work);
536 cancel_work_sync(&strp->work); 535 cancel_work_sync(&strp->work);
537 536
538 if (strp->skb_head) { 537 if (strp->skb_head) {