diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/809-jailhouse-0003-ivshmem-net-fix-race-in-state-machine.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/809-jailhouse-0003-ivshmem-net-fix-race-in-state-machine.patch | 136 |
1 files changed, 0 insertions, 136 deletions
diff --git a/target/linux/layerscape/patches-5.4/809-jailhouse-0003-ivshmem-net-fix-race-in-state-machine.patch b/target/linux/layerscape/patches-5.4/809-jailhouse-0003-ivshmem-net-fix-race-in-state-machine.patch deleted file mode 100644 index ae6f839011..0000000000 --- a/target/linux/layerscape/patches-5.4/809-jailhouse-0003-ivshmem-net-fix-race-in-state-machine.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0af5d7d021bb899d9c3880415267e178a20fb7a9 Mon Sep 17 00:00:00 2001 -From: Mans Rullgard <mans@mansr.com> -Date: Thu, 24 Nov 2016 18:46:41 +0000 -Subject: [PATCH] ivshmem-net: fix race in state machine - -(cherry picked from commit 5d663baed6a89d09bae4446f6509f9957c780bc7) ---- - drivers/net/ivshmem-net.c | 60 ++++++++++++++++++++++++----------------------- - 1 file changed, 31 insertions(+), 29 deletions(-) - ---- a/drivers/net/ivshmem-net.c -+++ b/drivers/net/ivshmem-net.c -@@ -36,6 +36,8 @@ - #define IVSHM_NET_STATE_READY 2 - #define IVSHM_NET_STATE_RUN 3 - -+#define IVSHM_NET_FLAG_RUN 0 -+ - #define IVSHM_NET_MTU_MIN 256 - #define IVSHM_NET_MTU_MAX 65535 - #define IVSHM_NET_MTU_DEF 16384 -@@ -96,6 +98,8 @@ struct ivshm_net { - u32 lstate; - u32 rstate; - -+ unsigned long flags; -+ - struct workqueue_struct *state_wq; - struct work_struct state_work; - -@@ -529,12 +533,32 @@ static void ivshm_net_run(struct net_dev - { - struct ivshm_net *in = netdev_priv(ndev); - -+ if (in->lstate < IVSHM_NET_STATE_READY) -+ return; -+ -+ if (!netif_running(ndev)) -+ return; -+ -+ if (test_and_set_bit(IVSHM_NET_FLAG_RUN, &in->flags)) -+ return; -+ - netif_start_queue(ndev); - napi_enable(&in->napi); - napi_schedule(&in->napi); - ivshm_net_set_state(in, IVSHM_NET_STATE_RUN); - } - -+static void ivshm_net_do_stop(struct net_device *ndev) -+{ -+ struct ivshm_net *in = netdev_priv(ndev); -+ -+ if (!test_and_clear_bit(IVSHM_NET_FLAG_RUN, &in->flags)) -+ return; -+ -+ netif_stop_queue(ndev); -+ napi_disable(&in->napi); -+} -+ - static void ivshm_net_state_change(struct work_struct *work) - { - struct ivshm_net *in = container_of(work, struct ivshm_net, state_work); -@@ -560,21 +584,13 @@ static void ivshm_net_state_change(struc - break; - - case IVSHM_NET_STATE_READY: -+ case IVSHM_NET_STATE_RUN: - if (rstate >= IVSHM_NET_STATE_READY) { - netif_carrier_on(ndev); -- if (ndev->flags & IFF_UP) -- ivshm_net_run(ndev); -+ ivshm_net_run(ndev); - } else { - netif_carrier_off(ndev); -- ivshm_net_set_state(in, IVSHM_NET_STATE_RESET); -- } -- break; -- -- case IVSHM_NET_STATE_RUN: -- if (rstate < IVSHM_NET_STATE_READY) { -- netif_stop_queue(ndev); -- napi_disable(&in->napi); -- netif_carrier_off(ndev); -+ ivshm_net_do_stop(ndev); - ivshm_net_set_state(in, IVSHM_NET_STATE_RESET); - } - break; -@@ -584,18 +600,13 @@ static void ivshm_net_state_change(struc - WRITE_ONCE(in->rstate, rstate); - } - --static bool ivshm_net_check_state(struct net_device *ndev) -+static void ivshm_net_check_state(struct net_device *ndev) - { - struct ivshm_net *in = netdev_priv(ndev); - u32 rstate = readl(&in->ivshm_regs->rstate); - -- if (rstate != READ_ONCE(in->rstate) || -- in->lstate != IVSHM_NET_STATE_RUN) { -+ if (rstate != in->rstate || !test_bit(IVSHM_NET_FLAG_RUN, &in->flags)) - queue_work(in->state_wq, &in->state_work); -- return false; -- } -- -- return true; - } - - static irqreturn_t ivshm_net_int(int irq, void *data) -@@ -617,24 +628,15 @@ static int ivshm_net_open(struct net_dev - - netdev_reset_queue(ndev); - ndev->operstate = IF_OPER_UP; -- -- if (in->lstate == IVSHM_NET_STATE_READY) -- ivshm_net_run(ndev); -+ ivshm_net_run(ndev); - - return 0; - } - - static int ivshm_net_stop(struct net_device *ndev) - { -- struct ivshm_net *in = netdev_priv(ndev); -- - ndev->operstate = IF_OPER_DOWN; -- -- if (in->lstate == IVSHM_NET_STATE_RUN) { -- napi_disable(&in->napi); -- netif_stop_queue(ndev); -- ivshm_net_set_state(in, IVSHM_NET_STATE_READY); -- } -+ ivshm_net_do_stop(ndev); - - return 0; - } |