From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1Zk5jv-0002Qn-6l for mharc-grub-devel@gnu.org; Thu, 08 Oct 2015 03:35:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36774) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zha8y-0007uQ-7K for grub-devel@gnu.org; Thu, 01 Oct 2015 05:27:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zha8u-00088E-2v for grub-devel@gnu.org; Thu, 01 Oct 2015 05:27:16 -0400 Received: from mgwkm03.jp.fujitsu.com ([202.219.69.170]:65436) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zha8t-00086b-Ls for grub-devel@gnu.org; Thu, 01 Oct 2015 05:27:12 -0400 Received: from kw-mxq.gw.nic.fujitsu.com (unknown [192.168.231.130]) by mgwkm03.jp.fujitsu.com with smtp id 5e69_4202_1f56dce5_115f_48b9_a5ab_2f4a2eab32e7; Thu, 01 Oct 2015 18:27:08 +0900 Received: from m3050.s.css.fujitsu.com (msm.b.css.fujitsu.com [10.134.21.208]) by kw-mxq.gw.nic.fujitsu.com (Postfix) with ESMTP id 8618EAC00B8 for ; Thu, 1 Oct 2015 18:27:07 +0900 (JST) Received: from localhost (WIN-36H9M1TN0Q4.g01.fujitsu.local [10.124.102.145]) by m3050.s.css.fujitsu.com (Postfix) with ESMTP id 55B61111; Thu, 1 Oct 2015 18:27:07 +0900 (JST) X-SecurityPolicyCheck: OK by SHieldMailChecker v2.2.3 X-SHieldMailCheckerPolicyVersion: FJ-ISEC-20140219-2 Date: Thu, 01 Oct 2015 18:26:55 +0900 (JST) Message-Id: <20151001.182655.371384337.d.hatayama@jp.fujitsu.com> To: grub-devel@gnu.org Subject: [PATCH] efinet: disable MNP background polling From: HATAYAMA Daisuke X-Mailer: Mew version 6.5 on Emacs 24.5 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-TM-AS-MML: disable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 202.219.69.170 Cc: arvidjaar@gmail.com, lersek@redhat.com, glin@suse.com X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Oct 2015 09:27:17 -0000 Currently, as of the commit f348aee7b33dd85e7da62b497a96a7319a0bf9dd, SNP is exclusively reopened to avoid slowdown or complete failure to load files due to races between MNP background polling and grub's receiving and transmitting packets. This exclusive SNP reopen affects some EFI applications/drivers that use SNP and causes PXE boot on such systems to fail. Hardware filter issue fixed by the commit 49426e9fd2e562c73a4f1206f32eff9e424a1a73 is one example. The difficulty here is that effects of the exclusive SNP reopen differs from system to system depending their UEFI firmware implementations. One system works well with the commit f348aee7b33dd85e7da62b497a96a7319a0bf9dd only, another system still needs the commit 49426e9fd2e562c73a4f1206f32eff9e424a1a73, and there could be other systems where PXE boot still fails. Actually, PXE boot fails on Fujitsu PRIMEQUEST 2000 series now. Thus, it seems to me that the exclusive SNP reopen makes grub maintenance difficult by affecting a variety of systems differently. Instead, the idea of this patch is to disable MNP background polling temporarily while grub uses SNP. Then, the race issue must be removed. I think origianal MNP configuration should be recovered before grub terminates, but this version doesn't do that because I didn't find a good place to do so. Before applying this patch, please revert the following 2 commits related to the exclusive SNP reopen: f348aee7b33dd85e7da62b497a96a7319a0bf9dd 49426e9fd2e562c73a4f1206f32eff9e424a1a73 I would highly appreciate if someone help testing on your environment because the origianal slow down issue doesn't occur on Fujitsu PRIMEQUEST 2000 seriees. --- grub-core/net/drivers/efi/efinet.c | 14 ++++++++++++++ include/grub/efi/api.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index c9af01c..a506ab3 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -29,6 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* GUID. */ static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; +static grub_efi_guid_t mnp_io_guid = GRUB_EFI_MANAGED_NETWORK_GUID; static grub_err_t send_card_buffer (struct grub_net_card *dev, @@ -269,6 +270,9 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, grub_efi_device_path_t *cdp; struct grub_efi_pxe *pxe; struct grub_efi_pxe_mode *pxe_mode; + grub_efi_managed_network_t *mnp; + struct grub_efi_managed_network_config_data m; + struct grub_efi_simple_network_mode s; if (card->driver != &efidriver) continue; cdp = grub_efi_get_device_path (card->efi_handle); @@ -312,6 +316,16 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, &pxe_mode->dhcp_ack, sizeof (pxe_mode->dhcp_ack), 1, device, path); + + mnp = grub_efi_open_protocol (card->efi_handle, &mnp_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (mnp + && efi_call_3 (mnp->get_mode_data, mnp, &m, &s) == GRUB_EFI_SUCCESS) { + m.disable_background_polling = 1; + efi_call_2 (mnp->configure, mnp, &m); + } + return; } } diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index e5dd543..e2baba2 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -286,6 +286,11 @@ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ } +#define GRUB_EFI_MANAGED_NETWORK_GUID \ + { 0x7ab33a91, 0xace5, 0x4326, \ + { 0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16} \ + } + struct grub_efi_sal_system_table { grub_uint32_t signature; @@ -1559,6 +1564,36 @@ struct grub_efi_block_io }; typedef struct grub_efi_block_io grub_efi_block_io_t; +struct grub_efi_managed_network_config_data +{ + grub_uint32_t received_queue_timeout_value; + grub_uint32_t transmit_queue_timeout_value; + grub_uint16_t protocol_type_filter; + grub_efi_boolean_t enable_unicast_receive; + grub_efi_boolean_t enable_multicast_receive; + grub_efi_boolean_t enable_broadcast_receive; + grub_efi_boolean_t enable_promiscuous_receive; + grub_efi_boolean_t flush_queues_on_reset; + grub_efi_boolean_t enable_receive_timestamps; + grub_efi_boolean_t disable_background_polling; +}; + +struct grub_efi_managed_network +{ + grub_efi_status_t (*get_mode_data) (struct grub_efi_managed_network *this, + struct grub_efi_managed_network_config_data *mnp_config, + struct grub_efi_simple_network_mode *snp_mode); + grub_efi_status_t (*configure) (struct grub_efi_managed_network *this, + struct grub_efi_managed_network_config_data *mnp_config); + void (*mcast_ip_to_mac) (void); + void (*groups) (void); + void (*transmit) (void); + void (*receive) (void); + void (*cancel) (void); + void (*poll) (void); +}; +typedef struct grub_efi_managed_network grub_efi_managed_network_t; + #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__)