Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp1259950iob; Thu, 19 May 2022 02:52:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJws6y7SUWIbSNL2o/HVceNL8iS0wlQNHXqXN2JaHBEDfFpRVXpnQvHnj8OqcG++kveZ+JR7 X-Received: by 2002:a05:6402:b8e:b0:42a:c086:11cd with SMTP id cf14-20020a0564020b8e00b0042ac08611cdmr4395185edb.166.1652953945703; Thu, 19 May 2022 02:52:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652953945; cv=none; d=google.com; s=arc-20160816; b=o9A/S5jT8x+FklJSGNqXpzFT3xa758Qyyw5rZC5ekZsiOCIVt7ytsYaCDvAhvDwC3+ y+1FVB/HyNPGisn3rx72hvLtf5TlhHrXmteNkbDVAkfL2Uh3RLkoNH951fxol9ayYlQM ElHRFkOJ7335k19FW6UfEkQ1jKHrvzKF0nRigmwn+7QraMkyGklgJ4smjg+kTW4C4KWR +vKiSdb/CevuzSnQxUS+FClxoqTn4mzOi+i31eSrMB2K8YaZwoOXOEnCO8i8sYHfXaZw l6zr+hxs1bRd/467H/Z0cj8Xl6awABn4HfQbJzLaOsXu8+LwDQ1W4vQa1gb/TNvTHS+7 DG+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4Bq05jMmGOSBQBP7BvGVwVSPmvwgQZYvbIERYnoCYA0=; b=Aq/D64gpD23BnXxtL+U0+rpb4VNoodgqxGa8bCvrCFpL8Vf5zkvHo2sIm8vtXwo7S8 vh6FSRm1OkwtR5AjmcHfbIAF4heYx/ragFbHZ6QtX+wQdPLEslNWG3QpJnK4MV4N1GQp ELRvrUJ0ixGEmSzh2Yvq+4q0bsxwJYj/LzLuBfSgYWGMMml27dQ3lNdzUaJ9DpmJU2e0 pUlDtaAmkSdF121mfQnQVoXyisy+U5nPXLviQTYi9hp45GC55PxHv+BzsnExXOt1I2dl 3fayR4TuHKtIwfyj61uDZlBrVe/i2stqKYVcby6SluN8X/vktKHE1CJJpPdKABR1xmam AK7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=ZRwTvThI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id he14-20020a1709073d8e00b006fdeef08e53si6827865ejc.380.2022.05.19.02.51.59; Thu, 19 May 2022 02:52:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=ZRwTvThI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234585AbiESHJn (ORCPT + 99 others); Thu, 19 May 2022 03:09:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232424AbiESHJZ (ORCPT ); Thu, 19 May 2022 03:09:25 -0400 Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A922B8BDE for ; Thu, 19 May 2022 00:09:22 -0700 (PDT) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 202205190709208ecca78304bb084a89 for ; Thu, 19 May 2022 09:09:21 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=daniel.starke@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=4Bq05jMmGOSBQBP7BvGVwVSPmvwgQZYvbIERYnoCYA0=; b=ZRwTvThIX1+8Vk3ZvLPBe6Fspc9Co9mxNX8FQLvpZ2dCWwf4OcSrR+/kjNYlgF54a8znCj Fucs9Z4/llHT1DQYmXlan6FpVIBCaXdNdKUHXMn4lW1/Re1R3Kk7ATLqDQXREx44BBpzoOA6 FaG3hChnupaB/x8q3TWysN7J5vH60=; From: "D. Starke" To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org, jirislaby@kernel.org Cc: linux-kernel@vger.kernel.org, Daniel Starke Subject: [PATCH v2 4/9] tty: n_gsm: fix missing timer to handle stalled links Date: Thu, 19 May 2022 09:07:52 +0200 Message-Id: <20220519070757.2096-4-daniel.starke@siemens.com> In-Reply-To: <20220519070757.2096-1-daniel.starke@siemens.com> References: <20220519070757.2096-1-daniel.starke@siemens.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-314044:519-21489:flowmailer X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Daniel Starke The current implementation does not handle the situation that no data is in the internal queue and needs to be sent out while the user tty fifo is full. Add a timer that moves more data from user tty down to the internal queue which is then serialized on the ldisc. This timer is triggered if no data was moved from a user tty to the internal queue within 10 * T1. Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Cc: stable@vger.kernel.org Signed-off-by: Daniel Starke --- drivers/tty/n_gsm.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) See patch 6 regarding changes since to v1. diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 0a9924445968..3a4a2394d970 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -244,6 +244,7 @@ struct gsm_mux { struct list_head tx_list; /* Pending data packets */ /* Control messages */ + struct timer_list kick_timer; /* Kick TX queuing on timeout */ struct timer_list t2_timer; /* Retransmit timer for commands */ int cretries; /* Command retry counter */ struct gsm_control *pending_cmd;/* Our current pending command */ @@ -833,6 +834,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) list_add_tail(&msg->list, &gsm->tx_list); gsm->tx_bytes += msg->len; gsm_data_kick(gsm, dlci); + mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100); } /** @@ -885,9 +887,6 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) size = len + h; msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); - /* FIXME: need a timer or something to kick this so it can't - * get stuck with no work outstanding and no buffer free - */ if (!msg) return -ENOMEM; dp = msg->data; @@ -964,9 +963,6 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, size = len + overhead; msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); - - /* FIXME: need a timer or something to kick this so it can't - get stuck with no work outstanding and no buffer free */ if (msg == NULL) { skb_queue_tail(&dlci->skb_list, dlci->skb); dlci->skb = NULL; @@ -1062,9 +1058,9 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci, * renegotiate DLCI priorities with optional stuff. Needs optimising. */ -static void gsm_dlci_data_sweep(struct gsm_mux *gsm) +static int gsm_dlci_data_sweep(struct gsm_mux *gsm) { - int len; + int len, ret = 0; /* Priority ordering: We should do priority with RR of the groups */ int i = 1; @@ -1087,7 +1083,11 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) /* DLCI empty - try the next */ if (len == 0) i++; + else + ret++; } + + return ret; } /** @@ -1806,6 +1806,30 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len) } } +/** + * gsm_kick_timer - transmit if possible + * @t: timer contained in our gsm object + * + * Transmit data from DLCIs if the queue is empty. We can't rely on + * a tty wakeup except when we filled the pipe so we need to fire off + * new data ourselves in other cases. + */ +static void gsm_kick_timer(struct timer_list *t) +{ + struct gsm_mux *gsm = from_timer(gsm, t, kick_timer); + unsigned long flags; + int sent = 0; + + spin_lock_irqsave(&gsm->tx_lock, flags); + /* If we have nothing running then we need to fire up */ + if (gsm->tx_bytes < TX_THRESH_LO) + sent = gsm_dlci_data_sweep(gsm); + spin_unlock_irqrestore(&gsm->tx_lock, flags); + + if (sent && debug & 4) + pr_info("%s TX queue stalled\n", __func__); +} + /* * Allocate/Free DLCI channels */ @@ -2261,6 +2285,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) } /* Finish outstanding timers, making sure they are done */ + del_timer_sync(&gsm->kick_timer); del_timer_sync(&gsm->t2_timer); /* Free up any link layer users and finally the control channel */ @@ -2293,6 +2318,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm) struct gsm_dlci *dlci; int ret; + timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); init_waitqueue_head(&gsm->event); spin_lock_init(&gsm->control_lock); @@ -2699,6 +2725,7 @@ static int gsmld_open(struct tty_struct *tty) gsmld_attach_gsm(tty, gsm); + timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); return 0; -- 2.34.1