Revert "bpf, sockmap: Improved check for empty queue"
This reverts commit ba4fec5bd6.
It breaks the Android KABI and will be brought back at a later time when
it is safe to do so.
Bug: 161946584
Change-Id: I95c2e59a4854c4e178d11b890e8401bc3cb64b68
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
51ffabff7c
commit
4903ee3f95
2 changed files with 25 additions and 8 deletions
|
|
@ -71,6 +71,7 @@ struct sk_psock_link {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sk_psock_work_state {
|
struct sk_psock_work_state {
|
||||||
|
struct sk_buff *skb;
|
||||||
u32 len;
|
u32 len;
|
||||||
u32 off;
|
u32 off;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -621,12 +621,16 @@ static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb,
|
||||||
|
|
||||||
static void sk_psock_skb_state(struct sk_psock *psock,
|
static void sk_psock_skb_state(struct sk_psock *psock,
|
||||||
struct sk_psock_work_state *state,
|
struct sk_psock_work_state *state,
|
||||||
|
struct sk_buff *skb,
|
||||||
int len, int off)
|
int len, int off)
|
||||||
{
|
{
|
||||||
spin_lock_bh(&psock->ingress_lock);
|
spin_lock_bh(&psock->ingress_lock);
|
||||||
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
|
if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
|
||||||
|
state->skb = skb;
|
||||||
state->len = len;
|
state->len = len;
|
||||||
state->off = off;
|
state->off = off;
|
||||||
|
} else {
|
||||||
|
sock_drop(psock->sk, skb);
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&psock->ingress_lock);
|
spin_unlock_bh(&psock->ingress_lock);
|
||||||
}
|
}
|
||||||
|
|
@ -637,17 +641,23 @@ static void sk_psock_backlog(struct work_struct *work)
|
||||||
struct sk_psock *psock = container_of(dwork, struct sk_psock, work);
|
struct sk_psock *psock = container_of(dwork, struct sk_psock, work);
|
||||||
struct sk_psock_work_state *state = &psock->work_state;
|
struct sk_psock_work_state *state = &psock->work_state;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
u32 len = 0, off = 0;
|
|
||||||
bool ingress;
|
bool ingress;
|
||||||
|
u32 len, off;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&psock->work_mutex);
|
mutex_lock(&psock->work_mutex);
|
||||||
if (unlikely(state->len)) {
|
if (unlikely(state->skb)) {
|
||||||
|
spin_lock_bh(&psock->ingress_lock);
|
||||||
|
skb = state->skb;
|
||||||
len = state->len;
|
len = state->len;
|
||||||
off = state->off;
|
off = state->off;
|
||||||
|
state->skb = NULL;
|
||||||
|
spin_unlock_bh(&psock->ingress_lock);
|
||||||
}
|
}
|
||||||
|
if (skb)
|
||||||
|
goto start;
|
||||||
|
|
||||||
while ((skb = skb_peek(&psock->ingress_skb))) {
|
while ((skb = skb_dequeue(&psock->ingress_skb))) {
|
||||||
len = skb->len;
|
len = skb->len;
|
||||||
off = 0;
|
off = 0;
|
||||||
if (skb_bpf_strparser(skb)) {
|
if (skb_bpf_strparser(skb)) {
|
||||||
|
|
@ -656,6 +666,7 @@ static void sk_psock_backlog(struct work_struct *work)
|
||||||
off = stm->offset;
|
off = stm->offset;
|
||||||
len = stm->full_len;
|
len = stm->full_len;
|
||||||
}
|
}
|
||||||
|
start:
|
||||||
ingress = skb_bpf_ingress(skb);
|
ingress = skb_bpf_ingress(skb);
|
||||||
skb_bpf_redirect_clear(skb);
|
skb_bpf_redirect_clear(skb);
|
||||||
do {
|
do {
|
||||||
|
|
@ -665,7 +676,8 @@ static void sk_psock_backlog(struct work_struct *work)
|
||||||
len, ingress);
|
len, ingress);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (ret == -EAGAIN) {
|
if (ret == -EAGAIN) {
|
||||||
sk_psock_skb_state(psock, state, len, off);
|
sk_psock_skb_state(psock, state, skb,
|
||||||
|
len, off);
|
||||||
|
|
||||||
/* Delay slightly to prioritize any
|
/* Delay slightly to prioritize any
|
||||||
* other work that might be here.
|
* other work that might be here.
|
||||||
|
|
@ -677,16 +689,15 @@ static void sk_psock_backlog(struct work_struct *work)
|
||||||
/* Hard errors break pipe and stop xmit. */
|
/* Hard errors break pipe and stop xmit. */
|
||||||
sk_psock_report_error(psock, ret ? -ret : EPIPE);
|
sk_psock_report_error(psock, ret ? -ret : EPIPE);
|
||||||
sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
|
sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
|
||||||
|
sock_drop(psock->sk, skb);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
off += ret;
|
off += ret;
|
||||||
len -= ret;
|
len -= ret;
|
||||||
} while (len);
|
} while (len);
|
||||||
|
|
||||||
skb = skb_dequeue(&psock->ingress_skb);
|
if (!ingress)
|
||||||
if (!ingress) {
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
mutex_unlock(&psock->work_mutex);
|
mutex_unlock(&psock->work_mutex);
|
||||||
|
|
@ -779,6 +790,11 @@ static void __sk_psock_zap_ingress(struct sk_psock *psock)
|
||||||
skb_bpf_redirect_clear(skb);
|
skb_bpf_redirect_clear(skb);
|
||||||
sock_drop(psock->sk, skb);
|
sock_drop(psock->sk, skb);
|
||||||
}
|
}
|
||||||
|
kfree_skb(psock->work_state.skb);
|
||||||
|
/* We null the skb here to ensure that calls to sk_psock_backlog
|
||||||
|
* do not pick up the free'd skb.
|
||||||
|
*/
|
||||||
|
psock->work_state.skb = NULL;
|
||||||
__sk_psock_purge_ingress_msg(psock);
|
__sk_psock_purge_ingress_msg(psock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -797,6 +813,7 @@ void sk_psock_stop(struct sk_psock *psock)
|
||||||
spin_lock_bh(&psock->ingress_lock);
|
spin_lock_bh(&psock->ingress_lock);
|
||||||
sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
|
sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
|
||||||
sk_psock_cork_free(psock);
|
sk_psock_cork_free(psock);
|
||||||
|
__sk_psock_zap_ingress(psock);
|
||||||
spin_unlock_bh(&psock->ingress_lock);
|
spin_unlock_bh(&psock->ingress_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -811,7 +828,6 @@ static void sk_psock_destroy(struct work_struct *work)
|
||||||
sk_psock_done_strp(psock);
|
sk_psock_done_strp(psock);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&psock->work);
|
cancel_delayed_work_sync(&psock->work);
|
||||||
__sk_psock_zap_ingress(psock);
|
|
||||||
mutex_destroy(&psock->work_mutex);
|
mutex_destroy(&psock->work_mutex);
|
||||||
|
|
||||||
psock_progs_drop(&psock->progs);
|
psock_progs_drop(&psock->progs);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue