Skip to content

Commit

Permalink
strparser: Use delayed work instead of timer for msg timeout
Browse files Browse the repository at this point in the history
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: bbb0302 ("strparser: Generalize strparser")
Signed-off-by: Tom Herbert <tom@quantonium.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Tom Herbert authored and davem330 committed Oct 25, 2017
1 parent 864f5af commit 829385f
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 11 deletions.
3 changes: 1 addition & 2 deletions include/net/strparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ struct strparser {
u32 unrecov_intr : 1;

struct sk_buff **skb_nextp;
struct timer_list msg_timer;
struct sk_buff *skb_head;
unsigned int need_bytes;
struct delayed_work delayed_work;
struct delayed_work msg_timer_work;
struct work_struct work;
struct strp_stats stats;
struct strp_callbacks cb;
Expand Down
17 changes: 8 additions & 9 deletions net/strparser/strparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
{
/* Unrecoverable error in receive */

del_timer(&strp->msg_timer);
cancel_delayed_work(&strp->msg_timer_work);

if (strp->stopped)
return;
Expand All @@ -68,7 +68,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
static void strp_start_timer(struct strparser *strp, long timeo)
{
if (timeo)
mod_timer(&strp->msg_timer, timeo);
mod_delayed_work(strp_wq, &strp->msg_timer_work, timeo);
}

/* Lower lock held */
Expand Down Expand Up @@ -319,7 +319,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
eaten += (cand_len - extra);

/* Hurray, we have a new message! */
del_timer(&strp->msg_timer);
cancel_delayed_work(&strp->msg_timer_work);
strp->skb_head = NULL;
STRP_STATS_INCR(strp->stats.msgs);

Expand Down Expand Up @@ -450,9 +450,10 @@ static void strp_work(struct work_struct *w)
do_strp_work(container_of(w, struct strparser, work));
}

static void strp_msg_timeout(unsigned long arg)
static void strp_msg_timeout(struct work_struct *w)
{
struct strparser *strp = (struct strparser *)arg;
struct strparser *strp = container_of(w, struct strparser,
msg_timer_work.work);

/* Message assembly timed out */
STRP_STATS_INCR(strp->stats.msg_timeouts);
Expand Down Expand Up @@ -505,9 +506,7 @@ int strp_init(struct strparser *strp, struct sock *sk,
strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done;
strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp;

setup_timer(&strp->msg_timer, strp_msg_timeout,
(unsigned long)strp);

INIT_DELAYED_WORK(&strp->msg_timer_work, strp_msg_timeout);
INIT_WORK(&strp->work, strp_work);

return 0;
Expand All @@ -532,7 +531,7 @@ void strp_done(struct strparser *strp)
{
WARN_ON(!strp->stopped);

del_timer_sync(&strp->msg_timer);
cancel_delayed_work_sync(&strp->msg_timer_work);
cancel_work_sync(&strp->work);

if (strp->skb_head) {
Expand Down

0 comments on commit 829385f

Please sign in to comment.