From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3A2FDA04F2; Mon, 30 Dec 2019 14:58:35 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9E7A21C11F; Mon, 30 Dec 2019 14:58:34 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 8B27E1C11D; Mon, 30 Dec 2019 14:58:32 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Dec 2019 05:58:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,375,1571727600"; d="scan'208";a="209017850" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga007.jf.intel.com with ESMTP; 30 Dec 2019 05:58:31 -0800 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 30 Dec 2019 05:58:31 -0800 Received: from FMSEDG001.ED.cps.intel.com (10.1.192.133) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 30 Dec 2019 05:58:30 -0800 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (104.47.55.108) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 30 Dec 2019 05:58:30 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QueZpdgEnkVF59P7BMr1w3WK/duYyjvDKP5DhW+nSXvzUfMunELwyoA17FCS9YvZZVfcemmYb1mGu8Ur4wk/ciTP6QqQ+DNT+wnOcaMJuxqZ9T36o23j/4gZWUP3OmFm1hi0eZPFLUR2bBVoTyqNiwETKAXiZYRgS1NsoMd1G+tsz9Cmm7IwaqwILCjaUpTTtX1v6ARsL8Oq+SL3nSbMygbpIGSjw69pIc0epnXneagv94RHWLjiDQJxuMpLLn3Upex7MV+JwceaDXp6PZsHIrkV9ywwVgqr2bE2nKZJD5S+LXApxuUNQV+PPg/RvgZ49wjSY1KRglyLxAc/OlXSIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6aVa7jrZn8kVtGeqAKCl/hev2qfX3E5SyrgNqjPAuAU=; b=jXoNJ8q01dVkv7ElRYoCqXE9lt4GcuzP5xiBxTKBBKsq23fWbDAQCf3C8jSbAkNFef5Tq9aMQhayR2hJRvRPFp6ZwH9fjs2BG3Ip+TqnxdFpCJQFtzsf2z4ecz/KWRXBACAPtzRQ9qNFzT1HSUvf/NmxqW/7rQjX+15vd26jEAc3cKJmLCnq8Iwo9BAn5K5DpiHoEGP2d5QgLXq6tS+CKl7WxfoqUlqE0MKebHSz81U9S+VMm/EpRTtmIlpT+XFptdjZzkIDvEsP+Up2iey11Oa1rwjjY1ubDOheHTjUYN+C9Q0GBrbb8BSIeqv/aCM11i3xBOQPj+7FCFa8/TEMzw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6aVa7jrZn8kVtGeqAKCl/hev2qfX3E5SyrgNqjPAuAU=; b=hCIikJ3YF5Xy71xfJj8QcmhK6htAVoOngiiaY4XTR98Qyp8eoblIpJ0PNONI9ojChUIbgYKI22upyxnfDBeJZgstLrC6uWOQB+hUHE+JYnk7Tcrj7mNJT4M4GF9s8vcBwnTb6uF2DTSSe1FcjJO71VhVrpN+BtWgTwk5kSZXkEw= Received: from SN6PR11MB2558.namprd11.prod.outlook.com (52.135.94.19) by SN6PR11MB2893.namprd11.prod.outlook.com (20.176.241.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2581.12; Mon, 30 Dec 2019 13:58:29 +0000 Received: from SN6PR11MB2558.namprd11.prod.outlook.com ([fe80::4d86:362a:13c3:8386]) by SN6PR11MB2558.namprd11.prod.outlook.com ([fe80::4d86:362a:13c3:8386%7]) with mapi id 15.20.2581.007; Mon, 30 Dec 2019 13:58:29 +0000 From: "Ananyev, Konstantin" To: "Zhu, TaoX" , "konstantin.ananyev@intel.com wenzhuo.lu@intel.com" <"konstantin.ananyev@intel.comwenzhuo.lu"@intel.com> CC: "dev@dpdk.org" , "stable@dpdk.org" Thread-Topic: [PATCH] net/ixgbe: fix blocking system events Thread-Index: AQHVu5b2suSAYbMK/0ejgMg/wdlOxafSrlrQ Date: Mon, 30 Dec 2019 13:58:28 +0000 Message-ID: References: <1577328342-216505-1-git-send-email-taox.zhu@intel.com> In-Reply-To: <1577328342-216505-1-git-send-email-taox.zhu@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYjY1NDRkODItMGM2Zi00ZTY5LWIzZjQtZThhNzk3NzEyNzhiIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoialdDU1BPejJrMGExTVB0eFJrVFBJTG1aNzVVUjhYYXFRaFNXMWx4OER1eVU4ZE02RElXUWhmaEhKK2o3VzlYZiJ9 dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.2.0.6 x-ctpclassification: CTP_NT authentication-results: spf=none (sender IP is ) smtp.mailfrom=konstantin.ananyev@intel.com; x-originating-ip: [46.7.38.224] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 563dcbed-5dcb-478d-13a0-08d78d305939 x-ms-traffictypediagnostic: SN6PR11MB2893: x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:386; x-forefront-prvs: 0267E514F9 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(136003)(366004)(376002)(396003)(346002)(39860400002)(189003)(199004)(86362001)(52536014)(478600001)(71200400001)(5660300002)(8936002)(4326008)(8676002)(55016002)(81166006)(81156014)(9686003)(316002)(7696005)(6506007)(2906002)(186003)(450100002)(26005)(66476007)(33656002)(66446008)(66556008)(76116006)(30864003)(54906003)(64756008)(66946007); DIR:OUT; SFP:1102; SCL:1; SRVR:SN6PR11MB2893; H:SN6PR11MB2558.namprd11.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: iLx/PSfCaUmIhbliaU+lv2b+9RMhA9HJl0n10NRkN+/MxvECaMGkHjkAtqTgg+U9ZppYRU5eLSFWi7aoDJPGPQQGs0qzO1VXwlaL32S1IKM8utATAThiNzsGoh5Zsq5gcT5mg+eVKHB3th6cN8sF/gjry/ZEn/GfwCy7ottotqlAilE3fUj4DDwuSmbxnmeUFHN0FrEChc0HslVag8ejQLCK+yAujPwhOCLzyx9Tvc3/5rMcZNOKXP8aRz3Wb7wo7GERaPHE7N2GpT7oi8PQj0VRB9YCZ5gH+nU9SR9/rSHuh11Abh8D52RBxmH8yYCSnZ38Tyv6n7ThD32bI12esGy1wpoL+YyPpeSME+zk54UFKm7HuaGj7Ly1yhRkp38u7tM9vMDtvMspIdXAnFtkRfUW2R6gvQD9PFq/e+kiTF3JxUTYY01O6HMSW41xSl8W Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 563dcbed-5dcb-478d-13a0-08d78d305939 X-MS-Exchange-CrossTenant-originalarrivaltime: 30 Dec 2019 13:58:28.8925 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: NKUZekfvF5Ki6qtkrvtB7dcBzJecXM1SCLbJ6BeEAbeNRgclaecVgCzUSS5YIlhGNzWzcCfBIzcU/z6n35HzACfaQwVb1NTPKFbTFFNcGuQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR11MB2893 X-OriginatorOrg: intel.com Subject: Re: [dpdk-dev] [PATCH] net/ixgbe: fix blocking system events X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi,=20 > IXGBE link status task use rte alarm thread in old implementation. > Sometime ixgbe link status task takes up to 9 seconds. This will > severely affect the rte-alarm-thread-dependent a task in the system, > like interrupt or hotplug event. So replace with a independent thread > which has the same thread affinity settings as rte interrupt. I don't think it is a good idea to add into PMD code that creates/manages new threads. I think ideal would be to rework link setup code, so it can take less time (make it interruptable/repeatable). If that is not possible, and control function is the only way, there is a wrapper function: rte_ctrl_thread_create() that can be used here instead of creating your own framework. =20 >=20 > Fixes: 0408f47b ("net/ixgbe: fix busy polling while fiber link update") > Cc: stable@dpdk.org >=20 > Signed-off-by: Zhu Tao > --- > drivers/net/ixgbe/ixgbe_ethdev.c | 184 +++++++++++++++++++++++++++++++++= ++++-- > drivers/net/ixgbe/ixgbe_ethdev.h | 32 +++++++ > 2 files changed, 210 insertions(+), 6 deletions(-) >=20 > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_e= thdev.c > index 2c6fd0f..f0b387d 100644 > --- a/drivers/net/ixgbe/ixgbe_ethdev.c > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include >=20 > #include > #include > @@ -378,6 +379,9 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_e= th_dev *dev, > struct rte_eth_udp_tunnel *udp_tunnel); > static int ixgbe_filter_restore(struct rte_eth_dev *dev); > static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev); > +static int ixgbe_task_thread_init(struct rte_eth_dev *dev); > +static void ixgbe_task_thread_uninit(struct rte_eth_dev *dev); > + >=20 > /* > * Define VF Stats MACRO for Non "cleared on read" register > @@ -1069,6 +1073,171 @@ struct rte_ixgbe_xstats_name_off { > } >=20 > /* > + * Add a task to task queue tail. > + */ > +int ixgbe_add_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb) > +{ > + struct ixgbe_adapter *ad =3D dev->data->dev_private; > + struct ixgbe_task *task; > + > + if (ad->task_status =3D=3D IXGBE_TASK_THREAD_RUNNING) { > + task =3D rte_zmalloc("ixgbe", sizeof(struct ixgbe_task), 0); > + if (task =3D=3D NULL) > + return -ENOMEM; > + > + task->arg =3D dev; > + task->task_cb =3D task_cb; > + task->status =3D IXGBE_TASK_READY; > + > + pthread_mutex_lock(&ad->task_lock); > + TAILQ_INSERT_TAIL(&ad->task_head, task, next); > + pthread_cond_signal(&ad->task_cond); > + pthread_mutex_unlock(&ad->task_lock); > + } else { > + return -EPERM; /* Operation not permitted */ > + } > + > + return 0; > +} > + > +/* > + * Sync cancel a task with all @task_cb be exit. > + */ > +int ixgbe_cancel_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb) > +{ > + struct ixgbe_adapter *ad =3D dev->data->dev_private; > + struct ixgbe_task *task, *ttask; > + int i, executing; > +#define DELAY_TIMEOUT_LOG 2000 // 2s > +#define DELAY_TIMEOUT_MAX 10000 // 10s > + > + for (i =3D 0; i < DELAY_TIMEOUT_MAX; i++) { > + executing =3D 0; > + if (ad->task_status =3D=3D IXGBE_TASK_THREAD_RUNNING) { > + pthread_mutex_lock(&ad->task_lock); > + TAILQ_FOREACH_SAFE(task, &ad->task_head, next, ttask) { > + if (task->task_cb =3D=3D task_cb) { > + if (task->status =3D=3D IXGBE_TASK_RUNNING) { > + executing++; > + } else { > + TAILQ_REMOVE(&ad->task_head, task, next); > + rte_free(task); > + } > + } > + } > + pthread_mutex_unlock(&ad->task_lock); > + > + if (executing) { > + if (i > DELAY_TIMEOUT_LOG && (i % 1000 =3D=3D 0)) { > + PMD_DRV_LOG(WARNING, > + "Cannel task time wait %ds!", i / 1000); > + } > + > + rte_delay_us_sleep(1000); // 1ms > + continue; > + } > + } > + break; > + } > + > + if (i =3D=3D DELAY_TIMEOUT_MAX) > + return -EBUSY; > + > + return 0; > +} > + > +/* > + * Task main thread. Loop until state is set to IXGBE_TASK_THREAD_EXIT. > + * For each task, set the status to IXGBE_TASK_RUNNING before execution, > + * execute and then be dequeue. > + */ > +static void *ixgbe_task_handler(void *args) > +{ > + struct ixgbe_adapter *ad =3D > + ((struct rte_eth_dev *)args)->data->dev_private; > + struct ixgbe_task *task; > + > + PMD_INIT_LOG(DEBUG, "ixgbe task thread created"); > + while (ad->task_status) { > + pthread_mutex_lock(&ad->task_lock); > + if (TAILQ_EMPTY(&ad->task_head)) { > + pthread_cond_wait(&ad->task_cond, &ad->task_lock); > + pthread_mutex_unlock(&ad->task_lock); > + continue; > + } > + > + /* pop firt task and run it */ > + task =3D TAILQ_FIRST(&ad->task_head); > + task->status =3D IXGBE_TASK_RUNNING; > + pthread_mutex_unlock(&ad->task_lock); > + > + if (task && task->task_cb) > + task->task_cb(task->arg); > + > + pthread_mutex_lock(&ad->task_lock); > + TAILQ_REMOVE(&ad->task_head, task, next); > + rte_free(task); > + pthread_mutex_unlock(&ad->task_lock); > + } > + > + pthread_mutex_lock(&ad->task_lock); > + while (!TAILQ_EMPTY(&ad->task_head)) { > + task =3D TAILQ_FIRST(&ad->task_head); > + TAILQ_REMOVE(&ad->task_head, task, next); > + rte_free(task); > + } > + pthread_mutex_unlock(&ad->task_lock); > + ad->task_status =3D IXGBE_TASK_THREAD_EXIT_DONE; > + > + return NULL; > +} > + > +static int ixgbe_task_thread_init(struct rte_eth_dev *dev) > +{ > + struct ixgbe_adapter *ad =3D dev->data->dev_private; > + struct rte_pci_device *pci_dev =3D RTE_ETH_DEV_TO_PCI(dev); > + char name[IXGBE_TASK_THREAD_NAME_LEN]; > + int ret; > + > + TAILQ_INIT(&ad->task_head); > + pthread_mutex_init(&ad->task_lock, NULL); > + pthread_cond_init(&ad->task_cond, NULL); > + > + snprintf(name, IXGBE_TASK_THREAD_NAME_LEN, "ixgbe-delay:%s", > + pci_dev->name); > + > + ret =3D rte_ctrl_thread_create(&ad->task_tid, name, NULL, > + ixgbe_task_handler, dev); > + if (ret < 0) { > + PMD_INIT_LOG(ERR, "Create control thread %s fail!", name); > + return ret; > + } > + ad->task_status =3D IXGBE_TASK_THREAD_RUNNING; > + > + return 0; > +} > + > +static void ixgbe_task_thread_uninit(struct rte_eth_dev *dev) > +{ > + struct ixgbe_adapter *ad =3D dev->data->dev_private; > + int i; > +#define MAX_EXIT_TIMEOUT 3000 /* 3s */ > + > + if (ad->task_status =3D=3D IXGBE_TASK_THREAD_RUNNING) { > + ad->task_status =3D IXGBE_TASK_THREAD_EXIT; > + pthread_cond_signal(&ad->task_cond); > + for (i =3D 0; i < MAX_EXIT_TIMEOUT; i++) { > + if (ad->task_status =3D=3D IXGBE_TASK_THREAD_EXIT_DONE) { > + pthread_cond_destroy(&ad->task_cond); > + pthread_mutex_destroy(&ad->task_lock); > + break; > + } > + rte_delay_us_sleep(1000); // 1ms > + } > + } > +} > + > +/* > * This function is based on code in ixgbe_attach() in base/ixgbe.c. > * It returns 0 on success. > */ > @@ -1301,6 +1470,7 @@ struct rte_ixgbe_xstats_name_off { > /* enable support intr */ > ixgbe_enable_intr(eth_dev); >=20 > + ixgbe_task_thread_init(eth_dev); > ixgbe_dev_set_link_down(eth_dev); >=20 > /* initialize filter info */ > @@ -1337,6 +1507,7 @@ struct rte_ixgbe_xstats_name_off { > return 0; >=20 > ixgbe_dev_close(eth_dev); > + ixgbe_task_thread_uninit(eth_dev); >=20 > return 0; > } > @@ -1713,6 +1884,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_d= ev *eth_dev) > ixgbevf_dev_interrupt_handler, eth_dev); > rte_intr_enable(intr_handle); > ixgbevf_intr_enable(eth_dev); > + ixgbe_task_thread_init(eth_dev); >=20 > PMD_INIT_LOG(DEBUG, "port %d vendorID=3D0x%x deviceID=3D0x%x mac.type= =3D%s", > eth_dev->data->port_id, pci_dev->id.vendor_id, > @@ -1732,6 +1904,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_d= ev *eth_dev) > return 0; >=20 > ixgbevf_dev_close(eth_dev); > + ixgbe_task_thread_uninit(eth_dev); >=20 > return 0; > } > @@ -2570,7 +2743,7 @@ static int eth_ixgbevf_pci_remove(struct rte_pci_de= vice *pci_dev) > } >=20 > /* Stop the link setup handler before resetting the HW. */ > - rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev); > + ixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler); >=20 > /* disable uio/vfio intr/eventfd mapping */ > rte_intr_disable(intr_handle); > @@ -2842,7 +3015,7 @@ static int eth_ixgbevf_pci_remove(struct rte_pci_de= vice *pci_dev) >=20 > PMD_INIT_FUNC_TRACE(); >=20 > - rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev); > + ixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler); >=20 > /* disable interrupts */ > ixgbe_disable_intr(hw); > @@ -4162,8 +4335,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unuse= d struct rte_eth_dev *dev, > if (link_up =3D=3D 0) { > if (ixgbe_get_media_type(hw) =3D=3D ixgbe_media_type_fiber) { > intr->flags |=3D IXGBE_FLAG_NEED_LINK_CONFIG; > - rte_eal_alarm_set(10, > - ixgbe_dev_setup_link_alarm_handler, dev); > + ixgbe_add_task(dev, ixgbe_dev_setup_link_alarm_handler); > } > return rte_eth_linkstatus_set(dev, &link); > } > @@ -5207,7 +5379,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unuse= d struct rte_eth_dev *dev, > PMD_INIT_FUNC_TRACE(); >=20 > /* Stop the link setup handler before resetting the HW. */ > - rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev); > + ixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler); >=20 > err =3D hw->mac.ops.reset_hw(hw); > if (err) { > @@ -5305,7 +5477,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unuse= d struct rte_eth_dev *dev, >=20 > PMD_INIT_FUNC_TRACE(); >=20 > - rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev); > + ixgbe_cancel_task(dev, ixgbe_dev_setup_link_alarm_handler); >=20 > ixgbevf_intr_disable(dev); >=20 > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_e= thdev.h > index 76a1b9d..4426349 100644 > --- a/drivers/net/ixgbe/ixgbe_ethdev.h > +++ b/drivers/net/ixgbe/ixgbe_ethdev.h > @@ -470,6 +470,28 @@ struct ixgbe_tm_conf { > bool committed; > }; >=20 > +#define IXGBE_TASK_THREAD_NAME_LEN 64 > +enum { > + IXGBE_TASK_THREAD_EXIT =3D 0, > + IXGBE_TASK_THREAD_RUNNING =3D 1, > + IXGBE_TASK_THREAD_EXIT_DONE =3D 2 > +}; > +enum { > + IXGBE_TASK_READY =3D 0, > + IXGBE_TASK_RUNNING =3D 1, > + IXGBE_TASK_FINISH =3D 2 > +}; > + > +typedef void (*ixgbe_task_cb_fn) (void *arg); > +struct ixgbe_task { > + TAILQ_ENTRY(ixgbe_task) next; > + void *arg; > + int status; > + ixgbe_task_cb_fn task_cb; > +}; > +TAILQ_HEAD(ixgbe_task_head, ixgbe_task); > + > + > /* > * Structure to store private data for each driver instance (for each po= rt). > */ > @@ -510,6 +532,13 @@ struct ixgbe_adapter { > * mailbox status) link status. > */ > uint8_t pflink_fullchk; > + > + /* Control thread per VF/PF, used for to do delay work */ > + pthread_t task_tid; > + struct ixgbe_task_head task_head; > + int task_status; > + pthread_mutex_t task_lock; > + pthread_cond_t task_cond; > }; >=20 > struct ixgbe_vf_representor { > @@ -760,6 +789,9 @@ void ixgbe_dev_macsec_setting_save(struct rte_eth_dev= *dev, > struct ixgbe_macsec_setting *macsec_setting); >=20 > void ixgbe_dev_macsec_setting_reset(struct rte_eth_dev *dev); > +int ixgbe_add_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb); > +int ixgbe_cancel_task(struct rte_eth_dev *dev, ixgbe_task_cb_fn task_cb)= ; > + >=20 > static inline int > ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info, > -- > 1.8.3.1