* [PATCH 1/3] net/cap: fix non-rt signal overflow
@ 2019-11-30 18:39 Philippe Gerum
2019-11-30 18:39 ` [PATCH 2/3] net/rtmac: vnic: " Philippe Gerum
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Philippe Gerum @ 2019-11-30 18:39 UTC (permalink / raw)
To: xenomai
From: Philippe Gerum <rpm@xenomai.org>
rtdm_nrtsig_pend() is based on ipipe_post_root_work(), which keeps a
copy of every request descriptor internally until it is consumed by
the secondary mode handler. Triggering rtdm_nrtsig_pend() every time a
packet is relayed from the stack to the tap device may cause such
request buffer to overflow under pressure.
To address this issue, trigger the non-rt signal only when the RX
queue transitions from empty to non-empty state as a result of
enqueuing the next skb.
Signed-off-by: Philippe Gerum <rpm@xenomai.org>
---
kernel/drivers/net/addons/cap.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/kernel/drivers/net/addons/cap.c b/kernel/drivers/net/addons/cap.c
index 5f83e19e3..293fcc84b 100644
--- a/kernel/drivers/net/addons/cap.c
+++ b/kernel/drivers/net/addons/cap.c
@@ -59,6 +59,7 @@ void rtcap_rx_hook(struct rtskb *rtskb)
{
int ifindex;
int active;
+ bool trigger = false;
if (rtskb->cap_flags & RTSKB_CAP_SHARED)
return;
@@ -81,9 +82,10 @@ void rtcap_rx_hook(struct rtskb *rtskb)
return;
}
- if (cap_queue.first == NULL)
+ if (cap_queue.first == NULL) {
cap_queue.first = rtskb;
- else
+ trigger = true;
+ } else
cap_queue.last->cap_next = rtskb;
cap_queue.last = rtskb;
rtskb->cap_next = NULL;
@@ -91,13 +93,15 @@ void rtcap_rx_hook(struct rtskb *rtskb)
rtskb->cap_flags |= RTSKB_CAP_SHARED;
rtskb->cap_dev = rtskb->rtdev;
- rtdm_nrtsig_pend(&cap_signal);
+ if (trigger)
+ rtdm_nrtsig_pend(&cap_signal);
}
int rtcap_xmit_hook(struct rtskb *rtskb, struct rtnet_device *rtdev)
{
struct tap_device_t *tap_dev = &tap_device[rtskb->rtdev->ifindex];
rtdm_lockctx_t context;
+ bool trigger = false;
int active;
active = tap_dev->present & XMIT_HOOK;
@@ -121,15 +125,17 @@ int rtcap_xmit_hook(struct rtskb *rtskb, struct rtnet_device *rtdev)
rtdm_lock_get_irqsave(&rtcap_lock, context);
- if (cap_queue.first == NULL)
+ if (cap_queue.first == NULL) {
cap_queue.first = rtskb;
- else
+ trigger = true;
+ } else
cap_queue.last->cap_next = rtskb;
cap_queue.last = rtskb;
rtdm_lock_put_irqrestore(&rtcap_lock, context);
- rtdm_nrtsig_pend(&cap_signal);
+ if (trigger)
+ rtdm_nrtsig_pend(&cap_signal);
done:
return tap_dev->orig_xmit(rtskb, rtdev);
}
--
2.21.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] net/rtmac: vnic: fix non-rt signal overflow
2019-11-30 18:39 [PATCH 1/3] net/cap: fix non-rt signal overflow Philippe Gerum
@ 2019-11-30 18:39 ` Philippe Gerum
2019-11-30 18:39 ` [PATCH 3/3] net/rtpc: " Philippe Gerum
2019-12-02 6:46 ` [PATCH 1/3] net/cap: " Jan Kiszka
2 siblings, 0 replies; 5+ messages in thread
From: Philippe Gerum @ 2019-11-30 18:39 UTC (permalink / raw)
To: xenomai
From: Philippe Gerum <rpm@xenomai.org>
rtdm_nrtsig_pend() is based on ipipe_post_root_work(), which keeps a
copy of every request descriptor internally until it is consumed by
the secondary mode handler. Triggering rtdm_nrtsig_pend() every time a
packet is relayed from the stack to the VNIC may cause such request
buffer to overflow under pressure.
To address this issue, trigger the non-rt signal only when the RX
queue transitions from empty to non-empty state as a result of
enqueuing the next skb.
Signed-off-by: Philippe Gerum <rpm@xenomai.org>
---
kernel/drivers/net/stack/rtmac/rtmac_vnic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/drivers/net/stack/rtmac/rtmac_vnic.c b/kernel/drivers/net/stack/rtmac/rtmac_vnic.c
index 85ee35002..138e276ad 100644
--- a/kernel/drivers/net/stack/rtmac/rtmac_vnic.c
+++ b/kernel/drivers/net/stack/rtmac/rtmac_vnic.c
@@ -52,8 +52,8 @@ int rtmac_vnic_rx(struct rtskb *rtskb, u16 type)
rtskb->protocol = type;
- rtskb_queue_tail(&rx_queue, rtskb);
- rtdm_nrtsig_pend(&vnic_signal);
+ if (rtskb_queue_tail_check(&rx_queue, rtskb))
+ rtdm_nrtsig_pend(&vnic_signal);
return 0;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] net/rtpc: fix non-rt signal overflow
2019-11-30 18:39 [PATCH 1/3] net/cap: fix non-rt signal overflow Philippe Gerum
2019-11-30 18:39 ` [PATCH 2/3] net/rtmac: vnic: " Philippe Gerum
@ 2019-11-30 18:39 ` Philippe Gerum
2019-12-02 6:46 ` [PATCH 1/3] net/cap: " Jan Kiszka
2 siblings, 0 replies; 5+ messages in thread
From: Philippe Gerum @ 2019-11-30 18:39 UTC (permalink / raw)
To: xenomai
From: Philippe Gerum <rpm@xenomai.org>
rtdm_nrtsig_pend() is based on ipipe_post_root_work(), which keeps a
copy of every request descriptor internally until it is consumed by
the secondary mode handler. Triggering rtdm_nrtsig_pend() every time a
packet is relayed from the stack to the tap device may cause such
request buffer to overflow under pressure.
To address this issue, trigger the non-rt signal only when the call
completion queue transitions from empty to non-empty state.
Signed-off-by: Philippe Gerum <rpm@xenomai.org>
---
kernel/drivers/net/stack/rtnet_rtpc.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/drivers/net/stack/rtnet_rtpc.c b/kernel/drivers/net/stack/rtnet_rtpc.c
index 4fcf5589e..cd5f0546d 100644
--- a/kernel/drivers/net/stack/rtnet_rtpc.c
+++ b/kernel/drivers/net/stack/rtnet_rtpc.c
@@ -146,12 +146,15 @@ static inline struct rt_proc_call *rtpc_dequeue_pending_call(void)
static inline void rtpc_queue_processed_call(struct rt_proc_call *call)
{
rtdm_lockctx_t context;
+ bool trigger;
rtdm_lock_get_irqsave(&processed_calls_lock, context);
+ trigger = list_empty(&processed_calls);
list_add_tail(&call->list_entry, &processed_calls);
rtdm_lock_put_irqrestore(&processed_calls_lock, context);
- rtdm_nrtsig_pend(&rtpc_nrt_signal);
+ if (trigger)
+ rtdm_nrtsig_pend(&rtpc_nrt_signal);
}
static inline struct rt_proc_call *rtpc_dequeue_processed_call(void)
--
2.21.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/3] net/cap: fix non-rt signal overflow
2019-11-30 18:39 [PATCH 1/3] net/cap: fix non-rt signal overflow Philippe Gerum
2019-11-30 18:39 ` [PATCH 2/3] net/rtmac: vnic: " Philippe Gerum
2019-11-30 18:39 ` [PATCH 3/3] net/rtpc: " Philippe Gerum
@ 2019-12-02 6:46 ` Jan Kiszka
2019-12-02 15:17 ` Philippe Gerum
2 siblings, 1 reply; 5+ messages in thread
From: Jan Kiszka @ 2019-12-02 6:46 UTC (permalink / raw)
To: Philippe Gerum, xenomai
On 30.11.19 19:39, Philippe Gerum via Xenomai wrote:
> From: Philippe Gerum <rpm@xenomai.org>
>
> rtdm_nrtsig_pend() is based on ipipe_post_root_work(), which keeps a
> copy of every request descriptor internally until it is consumed by
> the secondary mode handler. Triggering rtdm_nrtsig_pend() every time a
> packet is relayed from the stack to the tap device may cause such
> request buffer to overflow under pressure.
>
> To address this issue, trigger the non-rt signal only when the RX
> queue transitions from empty to non-empty state as a result of
> enqueuing the next skb.
>
> Signed-off-by: Philippe Gerum <rpm@xenomai.org>
> ---
> kernel/drivers/net/addons/cap.c | 18 ++++++++++++------
> 1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/drivers/net/addons/cap.c b/kernel/drivers/net/addons/cap.c
> index 5f83e19e3..293fcc84b 100644
> --- a/kernel/drivers/net/addons/cap.c
> +++ b/kernel/drivers/net/addons/cap.c
> @@ -59,6 +59,7 @@ void rtcap_rx_hook(struct rtskb *rtskb)
> {
> int ifindex;
> int active;
> + bool trigger = false;
>
> if (rtskb->cap_flags & RTSKB_CAP_SHARED)
> return;
> @@ -81,9 +82,10 @@ void rtcap_rx_hook(struct rtskb *rtskb)
> return;
> }
>
> - if (cap_queue.first == NULL)
> + if (cap_queue.first == NULL) {
> cap_queue.first = rtskb;
> - else
> + trigger = true;
> + } else
> cap_queue.last->cap_next = rtskb;
> cap_queue.last = rtskb;
> rtskb->cap_next = NULL;
> @@ -91,13 +93,15 @@ void rtcap_rx_hook(struct rtskb *rtskb)
> rtskb->cap_flags |= RTSKB_CAP_SHARED;
> rtskb->cap_dev = rtskb->rtdev;
>
> - rtdm_nrtsig_pend(&cap_signal);
> + if (trigger)
> + rtdm_nrtsig_pend(&cap_signal);
> }
>
> int rtcap_xmit_hook(struct rtskb *rtskb, struct rtnet_device *rtdev)
> {
> struct tap_device_t *tap_dev = &tap_device[rtskb->rtdev->ifindex];
> rtdm_lockctx_t context;
> + bool trigger = false;
> int active;
>
> active = tap_dev->present & XMIT_HOOK;
> @@ -121,15 +125,17 @@ int rtcap_xmit_hook(struct rtskb *rtskb, struct rtnet_device *rtdev)
>
> rtdm_lock_get_irqsave(&rtcap_lock, context);
>
> - if (cap_queue.first == NULL)
> + if (cap_queue.first == NULL) {
> cap_queue.first = rtskb;
> - else
> + trigger = true;
> + } else
> cap_queue.last->cap_next = rtskb;
> cap_queue.last = rtskb;
>
> rtdm_lock_put_irqrestore(&rtcap_lock, context);
>
> - rtdm_nrtsig_pend(&cap_signal);
> + if (trigger)
> + rtdm_nrtsig_pend(&cap_signal);
> done:
> return tap_dev->orig_xmit(rtskb, rtdev);
> }
>
Doesn't apply to next - what's your baseline?
Taking patch 2 and 3 meanwhile.
Jan
--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/3] net/cap: fix non-rt signal overflow
2019-12-02 6:46 ` [PATCH 1/3] net/cap: " Jan Kiszka
@ 2019-12-02 15:17 ` Philippe Gerum
0 siblings, 0 replies; 5+ messages in thread
From: Philippe Gerum @ 2019-12-02 15:17 UTC (permalink / raw)
To: Jan Kiszka, xenomai
On 12/2/19 7:46 AM, Jan Kiszka wrote:
> On 30.11.19 19:39, Philippe Gerum via Xenomai wrote:
>> From: Philippe Gerum <rpm@xenomai.org>
>>
>> rtdm_nrtsig_pend() is based on ipipe_post_root_work(), which keeps a
>> copy of every request descriptor internally until it is consumed by
>> the secondary mode handler. Triggering rtdm_nrtsig_pend() every time a
>> packet is relayed from the stack to the tap device may cause such
>> request buffer to overflow under pressure.
>>
>> To address this issue, trigger the non-rt signal only when the RX
>> queue transitions from empty to non-empty state as a result of
>> enqueuing the next skb.
>>
>> Signed-off-by: Philippe Gerum <rpm@xenomai.org>
>> ---
>> kernel/drivers/net/addons/cap.c | 18 ++++++++++++------
>> 1 file changed, 12 insertions(+), 6 deletions(-)
>>
>> diff --git a/kernel/drivers/net/addons/cap.c b/kernel/drivers/net/addons/cap.c
>> index 5f83e19e3..293fcc84b 100644
>> --- a/kernel/drivers/net/addons/cap.c
>> +++ b/kernel/drivers/net/addons/cap.c
>> @@ -59,6 +59,7 @@ void rtcap_rx_hook(struct rtskb *rtskb)
>> {
>> int ifindex;
>> int active;
>> + bool trigger = false;
>> if (rtskb->cap_flags & RTSKB_CAP_SHARED)
>> return;
>> @@ -81,9 +82,10 @@ void rtcap_rx_hook(struct rtskb *rtskb)
>> return;
>> }
>> - if (cap_queue.first == NULL)
>> + if (cap_queue.first == NULL) {
>> cap_queue.first = rtskb;
>> - else
>> + trigger = true;
>> + } else
>> cap_queue.last->cap_next = rtskb;
>> cap_queue.last = rtskb;
>> rtskb->cap_next = NULL;
>> @@ -91,13 +93,15 @@ void rtcap_rx_hook(struct rtskb *rtskb)
>> rtskb->cap_flags |= RTSKB_CAP_SHARED;
>> rtskb->cap_dev = rtskb->rtdev;
>> - rtdm_nrtsig_pend(&cap_signal);
>> + if (trigger)
>> + rtdm_nrtsig_pend(&cap_signal);
>> }
>> int rtcap_xmit_hook(struct rtskb *rtskb, struct rtnet_device *rtdev)
>> {
>> struct tap_device_t *tap_dev = &tap_device[rtskb->rtdev->ifindex];
>> rtdm_lockctx_t context;
>> + bool trigger = false;
>> int active;
>> active = tap_dev->present & XMIT_HOOK;
>> @@ -121,15 +125,17 @@ int rtcap_xmit_hook(struct rtskb *rtskb, struct rtnet_device *rtdev)
>> rtdm_lock_get_irqsave(&rtcap_lock, context);
>> - if (cap_queue.first == NULL)
>> + if (cap_queue.first == NULL) {
>> cap_queue.first = rtskb;
>> - else
>> + trigger = true;
>> + } else
>> cap_queue.last->cap_next = rtskb;
>> cap_queue.last = rtskb;
>> rtdm_lock_put_irqrestore(&rtcap_lock, context);
>> - rtdm_nrtsig_pend(&cap_signal);
>> + if (trigger)
>> + rtdm_nrtsig_pend(&cap_signal);
>> done:
>> return tap_dev->orig_xmit(rtskb, rtdev);
>> }
>>
>
> Doesn't apply to next - what's your baseline?
>
Mm, sorry. That one went on top of the multicast+VLAN support which is pending in my rtnet queue. A patch rebased on -next is on its way.
--
Philippe.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-12-02 15:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-30 18:39 [PATCH 1/3] net/cap: fix non-rt signal overflow Philippe Gerum
2019-11-30 18:39 ` [PATCH 2/3] net/rtmac: vnic: " Philippe Gerum
2019-11-30 18:39 ` [PATCH 3/3] net/rtpc: " Philippe Gerum
2019-12-02 6:46 ` [PATCH 1/3] net/cap: " Jan Kiszka
2019-12-02 15:17 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.