Net vm deadlock fix, version 4
Subsystems (9)
RFC 1/1 Net vm deadlock fix, version 4
Hi,
This patch fills in some missing pieces:
* Support v4 udp: same as v4 tcp, when in reserve, drop packets on noncritical sockets
* Support v4 icmp: when in reserve, drop icmp traffic
* Add reserve skb support to e1000 driver
* API for dropping packets before delivery (dev_drop_skb)
* Atomic_t for reserve accounting
Now ready for proof-of-concept testing. High level API boilerplate will come later.
Regards,
Daniel
drivers/net/e1000/e1000_main.c +1 -3
@@ -3242,7 +3242,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_acpu_to_le64 (ps_page_dma->ps_page_dma[j]); } - skb =dev_alloc_skb (adapter->rx_ps_bsize0 +NET_IP_ALIGN ); + skb =dev_memalloc_skb (netdev, adapter->rx_ps_bsize0 +NET_IP_ALIGN );if (unlikely (!skb))break ;
@@ -3253,8 +3253,6 @@ e1000_alloc_rx_buffers_ps(struct e1000_a*/ skb_reserve (skb,NET_IP_ALIGN ); - skb->dev = netdev; - buffer_info->skb = skb; buffer_info->length = adapter->rx_ps_bsize0; buffer_info->dma = pci_map_single(pdev, skb->data,
include/linux/gfp.h +1 -0
@@ -39,6 +39,7 @@ struct vm_area_struct;#define __GFP_COMP 0x4000u/* Add compound page metadata */ #define __GFP_ZERO 0x8000u/* Return zeroed page on success */ #define __GFP_NOMEMALLOC 0x10000u/* Don't use emergency reserves */ +#define __GFP_MEMALLOC 0x20000u/* Use emergency reserves */ #define __GFP_BITS_SHIFT 20/* Room for 20 __GFP_FOO bits */ #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
include/linux/netdevice.h +45 -0
57 lines not on this page · raw message
include/net/sock.h +6 -0
@@ -382,6 +382,7 @@ enum sock_flags {SOCK_NO_LARGESEND ,/* whether to sent large segments or not */ SOCK_LOCALROUTE ,/* route locally only, %SO_DONTROUTE setting */ SOCK_QUEUE_SHRUNK ,/* write queue has been shrunk recently */ + SOCK_MEMALLOC, /* protocol can use memalloc reserve */ };static inline void sock_set_flag (struct sock *sk,enum sock_flags flag)
@@ -399,6 +400,11 @@ static inline int sock_flag(struct sockreturn test_bit (flag, &sk->sk_flags); } +static inline int is_memalloc_sock (struct sock *sk) +{ +return sock_flag (sk,SOCK_MEMALLOC ); +} +static inline void sk_acceptq_removed (struct sock *sk) { sk->sk_ack_backlog--;
mm/page_alloc.c +2 -2
@@ -802,8 +802,8 @@ __alloc_pages(unsigned int __nocast gfp_/* This allocation should allow future memory freeing. */ -if (((p->flags &PF_MEMALLOC ) ||unlikely (test_thread_flag (TIF_MEMDIE ))) - && !in_interrupt ()) { +if ((((p->flags &PF_MEMALLOC ) ||unlikely (test_thread_flag (TIF_MEMDIE ))) + && !in_interrupt ()) || (gfp_mask & __GFP_MEMALLOC)) {if (!(gfp_mask & __GFP_NOMEMALLOC)) {/* go through the zonelist yet again, ignoring mins */ for (i =0 ; (z = zones[i]) !=NULL ; i++) {
net/ethernet/eth.c +1 -0
@@ -281,6 +281,7 @@ void ether_setup(struct net_device *dev) dev->mtu =1500 ;/* eth_mtu */ dev->addr_len =ETH_ALEN ; dev->tx_queue_len =1000 ;/* Ethernet wants good queues */ + dev->rx_reserve =50 ; dev->flags =IFF_BROADCAST |IFF_MULTICAST ;memset (dev->broadcast,0xFF ,ETH_ALEN );
net/ipv4/icmp.c +5 -0
@@ -944,6 +944,11 @@ int icmp_rcv(struct sk_buff *skb)default :; } +if (dev_reserve_used (skb->dev)) { +dev_unreserve (skb->dev); + goto drop; + } +if (!pskb_pull (skb,sizeof (struct icmphdr ))) goto error;
net/ipv4/tcp_ipv4.c +6 -0
@@ -1766,6 +1766,12 @@ int tcp_v4_rcv(struct sk_buff *skb)if (!sk) goto no_tcp_socket; +if (unlikely (dev_reserve_used (skb->dev))) { +dev_unreserve (skb->dev); +if (!is_memalloc_sock (sk)) + goto discard_and_relse; + } + process:if (sk->sk_state ==TCP_TIME_WAIT ) goto do_time_wait;
net/ipv4/udp.c +7 -0
@@ -1152,6 +1152,12 @@ int udp_rcv(struct sk_buff *skb) sk =udp_v4_lookup (saddr, uh->source, daddr, uh->dest, skb->dev->ifindex);if (sk !=NULL ) { +if (unlikely (dev_reserve_used (skb->dev))) { +dev_unreserve (skb->dev); +if (!is_memalloc_sock (sk)) + goto drop_noncritical; + } +int ret =udp_queue_rcv_skb (sk, skb);sock_put (sk);
@@ -1163,6 +1169,7 @@ int udp_rcv(struct sk_buff *skb)return 0 ; } +drop_noncritical:if (!xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) goto drop;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>