From owner-svn-src-head@freebsd.org Tue May 26 15:50:31 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1D0332CBE47; Tue, 26 May 2020 15:50:31 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49Wdhk71xVz4PwL; Tue, 26 May 2020 15:50:30 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id EC7EE25D42; Tue, 26 May 2020 15:50:30 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 04QFoUvp070797; Tue, 26 May 2020 15:50:30 GMT (envelope-from mw@FreeBSD.org) Received: (from mw@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 04QFoUbd070794; Tue, 26 May 2020 15:50:30 GMT (envelope-from mw@FreeBSD.org) Message-Id: <202005261550.04QFoUbd070794@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mw set sender to mw@FreeBSD.org using -f From: Marcin Wojtas Date: Tue, 26 May 2020 15:50:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r361523 - head/sys/dev/ena X-SVN-Group: head X-SVN-Commit-Author: mw X-SVN-Commit-Paths: head/sys/dev/ena X-SVN-Commit-Revision: 361523 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 15:50:31 -0000 Author: mw Date: Tue May 26 15:50:30 2020 New Revision: 361523 URL: https://svnweb.freebsd.org/changeset/base/361523 Log: Rework ENA Tx buffer ring size reconfiguration This method has been aligned with the way how the Rx queue size is being updated - so it's now done synchronously instead of resetting the device. Moreover, the input parameter is now being validated if it's a power of 2. Without this, it can cause kernel panic. Submitted by: Michal Krawczyk Obtained from: Semihalf Sponsored by: Amazon, Inc. Modified: head/sys/dev/ena/ena.c head/sys/dev/ena/ena.h head/sys/dev/ena/ena_sysctl.c Modified: head/sys/dev/ena/ena.c ============================================================================== --- head/sys/dev/ena/ena.c Tue May 26 15:48:27 2020 (r361522) +++ head/sys/dev/ena/ena.c Tue May 26 15:50:30 2020 (r361523) @@ -1135,6 +1135,55 @@ ena_refill_rx_bufs(struct ena_ring *rx_ring, uint32_t } int +ena_update_buf_ring_size(struct ena_adapter *adapter, + uint32_t new_buf_ring_size) +{ + uint32_t old_buf_ring_size; + int rc = 0; + bool dev_was_up; + + ENA_LOCK_LOCK(adapter); + + old_buf_ring_size = adapter->buf_ring_size; + adapter->buf_ring_size = new_buf_ring_size; + + dev_was_up = ENA_FLAG_ISSET(ENA_FLAG_DEV_UP, adapter); + ena_down(adapter); + + /* Reconfigure buf ring for all Tx rings. */ + ena_free_all_io_rings_resources(adapter); + ena_init_io_rings_advanced(adapter); + if (dev_was_up) { + /* + * If ena_up() fails, it's not because of recent buf_ring size + * changes. Because of that, we just want to revert old drbr + * value and trigger the reset because something else had to + * go wrong. + */ + rc = ena_up(adapter); + if (unlikely(rc != 0)) { + device_printf(adapter->pdev, + "Failed to configure device after setting new drbr size: %u. Reverting old value: %u and triggering the reset\n", + new_buf_ring_size, old_buf_ring_size); + + /* Revert old size and trigger the reset */ + adapter->buf_ring_size = old_buf_ring_size; + ena_free_all_io_rings_resources(adapter); + ena_init_io_rings_advanced(adapter); + + ENA_FLAG_SET_ATOMIC(ENA_FLAG_DEV_UP_BEFORE_RESET, + adapter); + ena_trigger_reset(adapter, ENA_REGS_RESET_OS_TRIGGER); + + } + } + + ENA_LOCK_UNLOCK(adapter); + + return (rc); +} + +int ena_update_queue_size(struct ena_adapter *adapter, uint32_t new_tx_size, uint32_t new_rx_size) { Modified: head/sys/dev/ena/ena.h ============================================================================== --- head/sys/dev/ena/ena.h Tue May 26 15:48:27 2020 (r361522) +++ head/sys/dev/ena/ena.h Tue May 26 15:50:30 2020 (r361523) @@ -426,7 +426,7 @@ struct ena_adapter { uint32_t tx_offload_cap; - uint16_t buf_ring_size; + uint32_t buf_ring_size; /* RSS*/ uint8_t rss_ind_tbl[ENA_RX_RSS_TABLE_SIZE]; @@ -497,6 +497,8 @@ void ena_down(struct ena_adapter *adapter); int ena_restore_device(struct ena_adapter *adapter); void ena_destroy_device(struct ena_adapter *adapter, bool graceful); int ena_refill_rx_bufs(struct ena_ring *rx_ring, uint32_t num); +int ena_update_buf_ring_size(struct ena_adapter *adapter, + uint32_t new_buf_ring_size); int ena_update_queue_size(struct ena_adapter *adapter, uint32_t new_tx_size, uint32_t new_rx_size); Modified: head/sys/dev/ena/ena_sysctl.c ============================================================================== --- head/sys/dev/ena/ena_sysctl.c Tue May 26 15:48:27 2020 (r361522) +++ head/sys/dev/ena/ena_sysctl.c Tue May 26 15:50:30 2020 (r361523) @@ -307,8 +307,9 @@ ena_sysctl_add_tuneables(struct ena_adapter *adapter) /* Tuneable number of buffers in the buf-ring (drbr) */ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "buf_ring_size", - CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, adapter, 0, - ena_sysctl_buf_ring_size, "I", "Size of the bufring"); + CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0, + ena_sysctl_buf_ring_size, "I", + "Size of the Tx buffer ring (drbr)."); /* Tuneable number of the Rx ring size */ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_queue_size", @@ -322,31 +323,38 @@ static int ena_sysctl_buf_ring_size(SYSCTL_HANDLER_ARGS) { struct ena_adapter *adapter = arg1; - int val; + uint32_t val; int error; val = 0; - error = sysctl_wire_old_buffer(req, sizeof(int)); + error = sysctl_wire_old_buffer(req, sizeof(val)); if (error == 0) { val = adapter->buf_ring_size; error = sysctl_handle_int(oidp, &val, 0, req); } if (error != 0 || req->newptr == NULL) return (error); - if (val < 0) + + if (!powerof2(val) || val == 0) { + device_printf(adapter->pdev, + "Requested new Tx buffer ring size (%u) is not a power of 2\n", + val); return (EINVAL); + } - device_printf(adapter->pdev, - "Requested new buf ring size: %d. Old size: %d\n", - val, adapter->buf_ring_size); - if (val != adapter->buf_ring_size) { - adapter->buf_ring_size = val; - adapter->reset_reason = ENA_REGS_RESET_OS_TRIGGER; - ENA_FLAG_SET_ATOMIC(ENA_FLAG_TRIGGER_RESET, adapter); + device_printf(adapter->pdev, + "Requested new Tx buffer ring size: %d. Old size: %d\n", + val, adapter->buf_ring_size); + + error = ena_update_buf_ring_size(adapter, val); + } else { + device_printf(adapter->pdev, + "New Tx buffer ring size is the same as already used: %u\n", + adapter->buf_ring_size); } - return (0); + return (error); } static int