Received: by 2002:a05:6602:18e:0:0:0:0 with SMTP id m14csp5442803ioo; Wed, 1 Jun 2022 05:47:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzCFNUcucvieaS3NyCIjopKLHipfKTGR1z9WNXKEfW9A9PLruWVeHAKqBeqocvFqVx21EZ6 X-Received: by 2002:a50:ee9a:0:b0:42d:cdf4:9501 with SMTP id f26-20020a50ee9a000000b0042dcdf49501mr18676951edr.226.1654087659917; Wed, 01 Jun 2022 05:47:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654087659; cv=none; d=google.com; s=arc-20160816; b=BTU2bENMhMm23d0B31VEq8HGEW95V90LnkrliDagzBYfYVYhMrPgqe0qjlXOFbaGIc VPFOO9oPigZ2DMqpqdsIcm53TpuqXn8VxC+vv2pCuOCbXyvbvXABmQGgEm778QGmgXGD q0N7UNRJIduS6Vy2KIOHX/Z0shnuiE26oH7FHUOlb9rZQyehWA1YrYn6snJwH/oIWMAj KJAjoxOl+p0AoFN6ocWi+mUXvJVP5t6hC+niLswuqt2b+quuTPqYDif4QgbPIpzASuNo vJA2yXg9Rnqvqndx467JJRYpmoU3uZr7eebxYXk1H34HvMJX8wALq+QnEcBbKv9l7/py Xeww== 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=37lGgpsTVFX6pGasppSwbTmEJqfdxwkpod/qzrWq4p4=; b=NJ7lIwP0Ogrnjf/HcTgYAKvp1uLYs7PZRacYl7KMzhwIp+/yjQnXsFtKFin1rGnA+H xxXcPQgeoHXUu1R9+B+61l2G6LDmjopCXSXqBpEB41mbRw0lh1XuPYe8pgSY2z2QohYp 92pzTvAilouTWdeBevkGwVq4nJTBQU9GZCYiVch/RUt2oqdXHq9Fby5zZMLKF7vjlaKa djRS6CyIYaxph6BdPwsFWsyiquQRP9MrsZF+y20A+SvVK7cgPb79lHHvwdy9oYWIT2D+ iOfrxSa7Bgn+QKs0C3bY2Rvk6QrH0HfWPJM4z4MWEtvg/7CjfVVk5PEq2g4ajaNvFDPw j0CQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=CblSyTmI; 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 hp42-20020a1709073e2a00b006feb8cc7e1fsi1865304ejc.1000.2022.06.01.05.47.12; Wed, 01 Jun 2022 05:47:39 -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=CblSyTmI; 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 S239087AbiE3Pjm (ORCPT + 99 others); Mon, 30 May 2022 11:39:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241193AbiE3Pih (ORCPT ); Mon, 30 May 2022 11:38:37 -0400 Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net [185.136.64.228]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1793D5E16B for ; Mon, 30 May 2022 07:46:29 -0700 (PDT) Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 20220530144627e8f28495de15159da1 for ; Mon, 30 May 2022 16:46:28 +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=37lGgpsTVFX6pGasppSwbTmEJqfdxwkpod/qzrWq4p4=; b=CblSyTmIGxYLtmdD9VBMl6FG5WJual5PAhVWA+hlAZ+U+ZM73My2oU3an0+U6Ia0VXXGBA BUo6TkMH/KEAye+/ZTpA2n6HdJnT2BpFLs+Ja6wGttB7o3gqqmVfwsZ0Fpj28JaKw67ncoJ3 dlTrXXlhRWJcQnAZlG/Kz6QQTGXxI=; 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 v3 3/9] tty: n_gsm: fix wrong queuing behavior in gsm_dlci_data_output() Date: Mon, 30 May 2022 16:45:06 +0200 Message-Id: <20220530144512.2731-3-daniel.starke@siemens.com> In-Reply-To: <20220530144512.2731-1-daniel.starke@siemens.com> References: <20220530144512.2731-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=unavailable 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 1) The function drains the fifo for the given user tty/DLCI without considering 'TX_THRESH_HI' and different to gsm_dlci_data_output_framed(), which moves only one packet from the user side to the internal transmission queue. We can only handle one packet at a time here if we want to allow DLCI priority handling in gsm_dlci_data_sweep() to avoid link starvation. 2) Furthermore, the additional header octet from convergence layer type 2 is not counted against MTU. It is part of the UI/UIH frame message which needs to be limited to MTU. Hence, it is wrong not to consider this octet. 3) Finally, the waiting user tty is not informed about freed space in its send queue. Take at most one packet worth of data out of the DLCI fifo to fix 1). Limit the max user data size per packet to MTU - 1 in case of convergence layer type 2 to leave space for the control signal octet which is added in the later part of the function. This fixes 2). Add tty_port_tty_wakeup() to wake up the user tty if new write space has been made available to fix 3). Fixes: 268e526b935e ("tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output") Cc: stable@vger.kernel.org Signed-off-by: Daniel Starke --- drivers/tty/n_gsm.c | 74 +++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 32 deletions(-) There have been no comments on v2, hence, no change was done. Link: https://lore.kernel.org/all/20220519070757.2096-3-daniel.starke@siemens.com/ diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 9b0bbd0d35d0..b51e2023d88d 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -869,41 +869,51 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) { struct gsm_msg *msg; u8 *dp; - int len, total_size, size; - int h = dlci->adaption - 1; + int h, len, size; - total_size = 0; - while (1) { - len = kfifo_len(&dlci->fifo); - if (len == 0) - return total_size; - - /* MTU/MRU count only the data bits */ - if (len > gsm->mtu) - len = gsm->mtu; - - 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 == NULL) - return -ENOMEM; - dp = msg->data; - switch (dlci->adaption) { - case 1: /* Unstructured */ - break; - case 2: /* Unstructed with modem bits. - Always one byte as we never send inline break data */ - *dp++ = (gsm_encode_modem(dlci) << 1) | EA; - break; - } - WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len); - __gsm_data_queue(dlci, msg); - total_size += size; + /* for modem bits without break data */ + h = ((dlci->adaption == 1) ? 0 : 1); + + len = kfifo_len(&dlci->fifo); + if (len == 0) + return 0; + + /* MTU/MRU count only the data bits but watch adaption mode */ + if ((len + h) > gsm->mtu) + len = gsm->mtu - h; + + 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; + switch (dlci->adaption) { + case 1: /* Unstructured */ + break; + case 2: /* Unstructured with modem bits. + * Always one byte as we never send inline break data + */ + *dp++ = (gsm_encode_modem(dlci) << 1) | EA; + break; + default: + pr_err("%s: unsupported adaption %d\n", __func__, + dlci->adaption); + break; } + + WARN_ON(len != kfifo_out_locked(&dlci->fifo, dp, len, + &dlci->lock)); + + /* Notify upper layer about available send space. */ + tty_port_tty_wakeup(&dlci->port); + + __gsm_data_queue(dlci, msg); /* Bytes of data we used up */ - return total_size; + return size; } /** -- 2.34.1