Re: [PATCH net] xfrm: Clear sk_dst_cache when applying per-socket policy.
On Mon, Oct 23, 2017 at 06:18:55PM -0700, Jonathan Basseri wrote: > If a socket has a valid dst cache, then xfrm_lookup_route will get > skipped. However, the cache is not invalidated when applying policy to a > socket (i.e. IPV6_XFRM_POLICY). The result is that new policies are > sometimes ignored on those sockets. (Note: This was broken for IPv4 and > IPv6 at different times.) > > This can be demonstrated like so, > 1. Create UDP socket. > 2. connect() the socket. > 3. Apply an outbound XFRM policy to the socket. > 4. send() data on the socket. > > Packets will continue to be sent in the clear instead of matching an > xfrm or returning a no-match error (EAGAIN). This affects calls to > send() and not sendto(). > > Invalidating the sk_dst_cache is necessary to correctly apply xfrm > policies. Since we do this in xfrm_user_policy(), the sk_lock was > already acquired in either do_ip_setsockopt() or do_ipv6_setsockopt(), > and we may call __sk_dst_reset(). > > Performance impact should be negligible, since this code is only called > when changing xfrm policy, and only affects the socket in question. > > Note: Creating normal XFRM policies should have a similar effect on > sk_dst_cache entries that match the policy, but that is not fixed in > this patch. I think we don't have this problem with 'normal' policies. When inserting such a policy, we bump the IPv4/IPv6 genid. This should invalidate all cached dst entries, no?
Re: [v3, 4/6] powerpc: dts: acadia: DT fix s/#interrupts-parent/#interrupt-parent/
On Fri, 2017-06-02 at 12:38:47 UTC, Geert Uytterhoeven wrote: > Signed-off-by: Geert Uytterhoeven > Acked-by: Rob Herring Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/3d2d4339cc326c427638daa67e264d cheers
[patch net-next] mlxsw: spectrum_dpipe: Fix entries dump of the adjacency table
From: Arkadi Sharshevsky During the dump the per netlink packet entry counter should be zeroed out when new packet is created. Fixes: 190d38a52a73 ("mlxsw: spectrum_dpipe: Add support for adjacency table dump") Signed-off-by: Arkadi Sharshevsky Reported-by: David Ahern Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c index 6ea6435..96fdba7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -1093,6 +1093,7 @@ mlxsw_sp_dpipe_table_adj_entries_get(struct mlxsw_sp *mlxsw_sp, goto err_ctx_prepare; j = 0; nh_skip = nh_count; + nh_count = 0; mlxsw_sp_nexthop_for_each(nh, mlxsw_sp->router) { if (!mlxsw_sp_nexthop_offload(nh) || mlxsw_sp_nexthop_group_has_ipip(nh)) -- 2.9.5
Re: [PATCH net-next 01/12] tools: bpftool: copy JSON writer from iproute2 repository
On Mon, 23 Oct 2017 09:24:05 -0700 Jakub Kicinski wrote: > From: Quentin Monnet > > In prevision of following commits, supposed to add JSON output to the > tool, two files are copied from the iproute2 repository (taken at commit > 268a9eee985f): lib/json_writer.c and include/json_writer.h. > > Signed-off-by: Quentin Monnet Acked-by: Stephen Hemminger
Re: [PATCH net-next 0/9] nfp: bpf: stack support in offload
From: Jakub Kicinski Date: Mon, 23 Oct 2017 11:58:05 -0700 > This series brings stack support for offload. Series applied, thanks Jakub.
Re: problem with rtnetlink 'reference' count
On Mon, Oct 23, 2017 at 09:37:03PM +0200, Florian Westphal wrote: > > OK, so then why not do something like so? > > @@ -260,10 +259,18 @@ void rtnl_unregister_all(int protocol) > > RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); > > rtnl_unlock(); > > > > + /* > > +* XXX explain what this is for... > > +*/ > > synchronize_net(); > > > > - while (refcount_read(&rtnl_msg_handlers_ref[protocol]) > 1) > > - schedule(); > > + /* > > +* This serializes against the rcu_read_lock() section in > > +* rtnetlink_rcv_msg() such that after this, all prior instances have > > +* completed and future instances must observe the NULL written above. > > +*/ > > + synchronize_rcu(); > > Yes, but that won't help with running dumpers, see below. > > > @@ -4218,7 +4223,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, > > struct nlmsghdr *nlh, > > }; > > err = netlink_dump_start(rtnl, skb, nlh, &c); > > This will copy .dumper function address to nlh->cb for later invocation > when dump gets resumed (its called from netlink_recvmsg()), > so this can return to userspace and dump can be resumed on next recv(). > > Because the dumper function was stored in the socket, NULLing the > rtnl_msg_handlers[] only prevents new dumps from starting but not > already set-up dumps from resuming. but netlink_dump_start() will actually grab a reference on the module; but it does so too late. Would it not be sufficient to put that try_module_get() under the rcu_read_lock()?
[PATCH] netfilter: ipvs: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Wensong Zhang Cc: Simon Horman Cc: Julian Anastasov Cc: Pablo Neira Ayuso Cc: Jozsef Kadlecsik Cc: Florian Westphal Cc: "David S. Miller" Cc: netdev@vger.kernel.org Cc: lvs-de...@vger.kernel.org Cc: netfilter-de...@vger.kernel.org Cc: coret...@netfilter.org Signed-off-by: Kees Cook --- net/netfilter/ipvs/ip_vs_conn.c | 10 +- net/netfilter/ipvs/ip_vs_ctl.c | 7 +++ net/netfilter/ipvs/ip_vs_est.c | 6 +++--- net/netfilter/ipvs/ip_vs_lblc.c | 11 ++- net/netfilter/ipvs/ip_vs_lblcr.c | 11 ++- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 3d2ac71a83ec..3a43b3470331 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -104,7 +104,7 @@ static inline void ct_write_unlock_bh(unsigned int key) spin_unlock_bh(&__ip_vs_conntbl_lock_array[key&CT_LOCKARRAY_MASK].l); } -static void ip_vs_conn_expire(unsigned long data); +static void ip_vs_conn_expire(struct timer_list *t); /* * Returns hash value for IPVS connection entry @@ -457,7 +457,7 @@ EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto); static void __ip_vs_conn_put_notimer(struct ip_vs_conn *cp) { __ip_vs_conn_put(cp); - ip_vs_conn_expire((unsigned long)cp); + ip_vs_conn_expire(&cp->timer); } /* @@ -817,9 +817,9 @@ static void ip_vs_conn_rcu_free(struct rcu_head *head) kmem_cache_free(ip_vs_conn_cachep, cp); } -static void ip_vs_conn_expire(unsigned long data) +static void ip_vs_conn_expire(struct timer_list *t) { - struct ip_vs_conn *cp = (struct ip_vs_conn *)data; + struct ip_vs_conn *cp = from_timer(cp, t, timer); struct netns_ipvs *ipvs = cp->ipvs; /* @@ -909,7 +909,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af, } INIT_HLIST_NODE(&cp->c_list); - setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp); + timer_setup(&cp->timer, ip_vs_conn_expire, 0); cp->ipvs = ipvs; cp->af = p->af; cp->daf= dest_af; diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 4f940d7eb2f7..b47e266c6eca 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1146,9 +1146,9 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) return 0; } -static void ip_vs_dest_trash_expire(unsigned long data) +static void ip_vs_dest_trash_expire(struct timer_list *t) { - struct netns_ipvs *ipvs = (struct netns_ipvs *)data; + struct netns_ipvs *ipvs = from_timer(ipvs, t, dest_trash_timer); struct ip_vs_dest *dest, *next; unsigned long now = jiffies; @@ -4019,8 +4019,7 @@ int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs) INIT_LIST_HEAD(&ipvs->dest_trash); spin_lock_init(&ipvs->dest_trash_lock); - setup_timer(&ipvs->dest_trash_timer, ip_vs_dest_trash_expire, - (unsigned long) ipvs); + timer_setup(&ipvs->dest_trash_timer, ip_vs_dest_trash_expire, 0); atomic_set(&ipvs->ftpsvc_counter, 0); atomic_set(&ipvs->nullsvc_counter, 0); atomic_set(&ipvs->conn_out_counter, 0); diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c index 457c6c193e13..489055091a9b 100644 --- a/net/netfilter/ipvs/ip_vs_est.c +++ b/net/netfilter/ipvs/ip_vs_est.c @@ -97,12 +97,12 @@ static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum, } -static void estimation_timer(unsigned long arg) +static void estimation_timer(struct timer_list *t) { struct ip_vs_estimator *e; struct ip_vs_stats *s; u64 rate; - struct netns_ipvs *ipvs = (struct netns_ipvs *)arg; + struct netns_ipvs *ipvs = from_timer(ipvs, t, est_timer); spin_lock(&ipvs->est_lock); list_for_each_entry(e, &ipvs->est_list, list) { @@ -192,7 +192,7 @@ int __net_init ip_vs_estimator_net_init(struct netns_ipvs *ipvs) { INIT_LIST_HEAD(&ipvs->est_list); spin_lock_init(&ipvs->est_lock); - setup_timer(&ipvs->est_timer, estimation_timer, (unsigned long)ipvs); + timer_setup(&ipvs->est_timer, estimation_timer, 0); mod_timer(&ipvs->est_timer, jiffies + 2 * HZ); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c index b6aa4a970c6e..d625179de485 100644 --- a/net/netfilter/ipvs/ip_vs_lblc.c +++ b/net/netfilter/ipvs/ip_vs_lblc.c @@ -106,6 +106,7 @@ struct ip_vs_lblc_table { struct rcu_head rcu_head; struct hlist_head bucket[IP_VS_LBLC_TAB_SIZE]; /* hash bucket */ struct timer_list periodic_timer; /* collect stale entries */
[PATCH] drivers/net: wan/sbni: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: David Howells Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wan/sbni.c | 21 - 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index bde8c0339831..8e8c4c0e1b64 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -71,6 +71,7 @@ struct net_local { struct timer_list watchdog; + struct net_device *watchdog_dev; spinlock_t lock; struct sk_buff *rx_buf_p; /* receive buffer ptr */ @@ -128,7 +129,7 @@ static void send_frame( struct net_device * ); static int upload_data( struct net_device *, unsigned, unsigned, unsigned, u32 ); static void download_data( struct net_device *, u32 * ); -static void sbni_watchdog( unsigned long ); +static void sbni_watchdog(struct timer_list *); static void interpret_ack( struct net_device *, unsigned ); static int append_frame_to_pkt( struct net_device *, unsigned, u32 ); static void indicate_pkt( struct net_device * ); @@ -1029,11 +1030,10 @@ indicate_pkt( struct net_device *dev ) */ static void -sbni_watchdog( unsigned long arg ) +sbni_watchdog(struct timer_list *t) { - struct net_device *dev = (struct net_device *) arg; - struct net_local *nl = netdev_priv(dev); - struct timer_list *w = &nl->watchdog; + struct net_local *nl = from_timer(nl, t, watchdog); + struct net_device *dev = nl->watchdog_dev; unsigned long flags; unsigned char csr0; @@ -1060,11 +1060,7 @@ sbni_watchdog( unsigned long arg ) outb( csr0 | RC_CHK, dev->base_addr + CSR0 ); - init_timer( w ); - w->expires = jiffies + SBNI_TIMEOUT; - w->data = arg; - w->function = sbni_watchdog; - add_timer( w ); + mod_timer(t, jiffies + SBNI_TIMEOUT); spin_unlock_irqrestore( &nl->lock, flags ); } @@ -1195,10 +1191,9 @@ sbni_open( struct net_device *dev ) netif_start_queue( dev ); /* set timer watchdog */ - init_timer( w ); + nl->watchdog_dev = dev; + timer_setup(w, sbni_watchdog, 0); w->expires = jiffies + SBNI_TIMEOUT; - w->data = (unsigned long) dev; - w->function = sbni_watchdog; add_timer( w ); spin_unlock( &nl->lock ); -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] net: atm/mpc: Stop using open-coded timer .data field
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using an explicit static variable to hold additional expiration details. Cc: "David S. Miller" Cc: Bhumika Goyal Cc: Andrew Morton Cc: Alexey Dobriyan Cc: "Reshetova, Elena" Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- net/atm/mpc.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/atm/mpc.c b/net/atm/mpc.c index b43d99430eb6..883d25778fa4 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -95,7 +95,7 @@ static netdev_tx_t mpc_send_packet(struct sk_buff *skb, static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned long event, void *dev); static void mpc_timer_refresh(void); -static void mpc_cache_check(unsigned long checking_time); +static void mpc_cache_check(struct timer_list *unused); static struct llc_snap_hdr llc_snap_mpoa_ctrl = { 0xaa, 0xaa, 0x03, @@ -1407,15 +1407,17 @@ static void clean_up(struct k_message *msg, struct mpoa_client *mpc, int action) msg_to_mpoad(msg, mpc); } +static unsigned long checking_time; + static void mpc_timer_refresh(void) { mpc_timer.expires = jiffies + (MPC_P2 * HZ); - mpc_timer.data = mpc_timer.expires; - mpc_timer.function = mpc_cache_check; + checking_time = mpc_timer.expires; + mpc_timer.function = (TIMER_FUNC_TYPE)mpc_cache_check; add_timer(&mpc_timer); } -static void mpc_cache_check(unsigned long checking_time) +static void mpc_cache_check(struct timer_list *unused) { struct mpoa_client *mpc = mpcs; static unsigned long previous_resolving_check_time; -- 2.7.4 -- Kees Cook Pixel Security
Re: [PATCH] net: xfrm_user: use BUG_ON instead of if condition followed by BUG
From: Herbert Xu Date: Tue, 24 Oct 2017 11:53:20 +0800 > No your patch makes it worse. The original construct makes it > clear that the conditional is real code and not just some debugging > aid. > > With your patch, real code is now inside BUG_ON. This discussion has happened before. But I'll explain the conclusion here for your benefit. BUG_ON() is a statement and everything inside of it will always execute. BUG_ON() is always preferred because it allows arch specific code to pass the conditional result properly into inline asm and builtins for optimal code generation.
Re: [PATCH] net: xfrm_user: use BUG_ON instead of if condition followed by BUG
From: Herbert Xu Date: Tue, 24 Oct 2017 11:25:08 +0800 > On Mon, Oct 23, 2017 at 01:18:57PM -0500, Gustavo A. R. Silva wrote: >> Use BUG_ON instead of if condition followed by BUG. >> >> This issue was detected with the help of Coccinelle. >> >> Signed-off-by: Gustavo A. R. Silva > > I think this patch is terrible. Why on earth is Coccinelle even > warning about this? BUG_ON(x) generates significantly better code than "if (cond) BUG();" because it's not possible to emit the most optimal code sequences like on powerpc that has conditional traps. That's why. I'm applying these transformations all over the networking as I receive them and I advise that you do so for crypto as well. Thank.
[PATCH] net: tipc: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Jon Maloy Cc: Ying Xue Cc: "David S. Miller" Cc: netdev@vger.kernel.org Cc: tipc-discuss...@lists.sourceforge.net Signed-off-by: Kees Cook --- net/tipc/discover.c | 6 +++--- net/tipc/monitor.c | 6 +++--- net/tipc/node.c | 8 net/tipc/socket.c | 10 +- net/tipc/subscr.c | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 02462d67d191..92e4828c6b09 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -224,9 +224,9 @@ void tipc_disc_remove_dest(struct tipc_link_req *req) * * Called whenever a link setup request timer associated with a bearer expires. */ -static void disc_timeout(unsigned long data) +static void disc_timeout(struct timer_list *t) { - struct tipc_link_req *req = (struct tipc_link_req *)data; + struct tipc_link_req *req = from_timer(req, t, timer); struct sk_buff *skb; int max_delay; @@ -292,7 +292,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b, req->num_nodes = 0; req->timer_intv = TIPC_LINK_REQ_INIT; spin_lock_init(&req->lock); - setup_timer(&req->timer, disc_timeout, (unsigned long)req); + timer_setup(&req->timer, disc_timeout, 0); mod_timer(&req->timer, jiffies + req->timer_intv); b->link_req = req; *skb = skb_clone(req->buf, GFP_ATOMIC); diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 9e109bb1a207..b9c32557d73c 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c @@ -578,9 +578,9 @@ void tipc_mon_get_state(struct net *net, u32 addr, read_unlock_bh(&mon->lock); } -static void mon_timeout(unsigned long m) +static void mon_timeout(struct timer_list *t) { - struct tipc_monitor *mon = (void *)m; + struct tipc_monitor *mon = from_timer(mon, t, timer); struct tipc_peer *self; int best_member_cnt = dom_size(mon->peer_cnt) - 1; @@ -623,7 +623,7 @@ int tipc_mon_create(struct net *net, int bearer_id) self->is_up = true; self->is_head = true; INIT_LIST_HEAD(&self->list); - setup_timer(&mon->timer, mon_timeout, (unsigned long)mon); + timer_setup(&mon->timer, mon_timeout, 0); mon->timer_intv = msecs_to_jiffies(MON_TIMEOUT + (tn->random & 0x)); mod_timer(&mon->timer, jiffies + mon->timer_intv); return 0; diff --git a/net/tipc/node.c b/net/tipc/node.c index 89f8ac73bf65..009a81631280 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -153,7 +153,7 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete); static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq); static void tipc_node_delete(struct tipc_node *node); -static void tipc_node_timeout(unsigned long data); +static void tipc_node_timeout(struct timer_list *t); static void tipc_node_fsm_evt(struct tipc_node *n, int evt); static struct tipc_node *tipc_node_find(struct net *net, u32 addr); static void tipc_node_put(struct tipc_node *node); @@ -361,7 +361,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities) goto exit; } tipc_node_get(n); - setup_timer(&n->timer, tipc_node_timeout, (unsigned long)n); + timer_setup(&n->timer, tipc_node_timeout, 0); n->keepalive_intv = U32_MAX; hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]); list_for_each_entry_rcu(temp_node, &tn->node_list, list) { @@ -500,9 +500,9 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port) /* tipc_node_timeout - handle expiration of node timer */ -static void tipc_node_timeout(unsigned long data) +static void tipc_node_timeout(struct timer_list *t) { - struct tipc_node *n = (struct tipc_node *)data; + struct tipc_node *n = from_timer(n, t, timer); struct tipc_link_entry *le; struct sk_buff_head xmitq; int bearer_id; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b3b72d8e9543..6387839f643d 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -125,7 +125,7 @@ static void tipc_sock_destruct(struct sock *sk); static int tipc_release(struct socket *sock); static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, bool kern); -static void tipc_sk_timeout(unsigned long data); +static void tipc_sk_timeout(struct timer_list *t); static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, struct tipc_name_seq const *seq); static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, @@ -464,7 +464,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, NAMED_H_SIZE, 0);
[PATCH] drivers/net: sis: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Francois Romieu Cc: Daniele Venzano Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/ethernet/sis/sis190.c | 10 -- drivers/net/ethernet/sis/sis900.c | 10 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 445109bd6910..c2c50522b96d 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c @@ -1018,10 +1018,10 @@ static void sis190_phy_task(struct work_struct *work) rtnl_unlock(); } -static void sis190_phy_timer(unsigned long __opaque) +static void sis190_phy_timer(struct timer_list *t) { - struct net_device *dev = (struct net_device *)__opaque; - struct sis190_private *tp = netdev_priv(dev); + struct sis190_private *tp = from_timer(tp, t, timer); + struct net_device *dev = tp->dev; if (likely(netif_running(dev))) schedule_work(&tp->phy_task); @@ -1039,10 +1039,8 @@ static inline void sis190_request_timer(struct net_device *dev) struct sis190_private *tp = netdev_priv(dev); struct timer_list *timer = &tp->timer; - init_timer(timer); + timer_setup(timer, sis190_phy_timer, 0); timer->expires = jiffies + SIS190_PHY_TIMEOUT; - timer->data = (unsigned long)dev; - timer->function = sis190_phy_timer; add_timer(timer); } diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index cb61247b0526..4bb89f74742c 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -218,7 +218,7 @@ static void sis900_init_rxfilter (struct net_device * net_dev); static u16 read_eeprom(void __iomem *ioaddr, int location); static int mdio_read(struct net_device *net_dev, int phy_id, int location); static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val); -static void sis900_timer(unsigned long data); +static void sis900_timer(struct timer_list *t); static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy); static void sis900_tx_timeout(struct net_device *net_dev); static void sis900_init_tx_ring(struct net_device *net_dev); @@ -1065,7 +1065,7 @@ sis900_open(struct net_device *net_dev) /* Set the timer to switch to check for link beat and perhaps switch to an alternate media type. */ - setup_timer(&sis_priv->timer, sis900_timer, (unsigned long)net_dev); + timer_setup(&sis_priv->timer, sis900_timer, 0); sis_priv->timer.expires = jiffies + HZ; add_timer(&sis_priv->timer); @@ -1300,10 +1300,10 @@ static void sis630_set_eq(struct net_device *net_dev, u8 revision) * link status (ON/OFF) and link mode (10/100/Full/Half) */ -static void sis900_timer(unsigned long data) +static void sis900_timer(struct timer_list *t) { - struct net_device *net_dev = (struct net_device *)data; - struct sis900_private *sis_priv = netdev_priv(net_dev); + struct sis900_private *sis_priv = from_timer(sis_priv, t, timer); + struct net_device *net_dev = sis_priv->mii_info.dev; struct mii_phy *mii_phy = sis_priv->mii; static const int next_tick = 5*HZ; int speed = 0, duplex = 0; -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] net: af_packet: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: "David S. Miller" Cc: Eric Dumazet Cc: Willem de Bruijn Cc: Mike Maloney Cc: Jarno Rajahalme Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- net/packet/af_packet.c | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 4f4fa323171d..9603f6ff17a4 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -201,11 +201,8 @@ static void prb_retire_current_block(struct tpacket_kbdq_core *, static int prb_queue_frozen(struct tpacket_kbdq_core *); static void prb_open_block(struct tpacket_kbdq_core *, struct tpacket_block_desc *); -static void prb_retire_rx_blk_timer_expired(unsigned long); +static void prb_retire_rx_blk_timer_expired(struct timer_list *); static void _prb_refresh_rx_retire_blk_timer(struct tpacket_kbdq_core *); -static void prb_init_blk_timer(struct packet_sock *, - struct tpacket_kbdq_core *, - void (*func) (unsigned long)); static void prb_fill_rxhash(struct tpacket_kbdq_core *, struct tpacket3_hdr *); static void prb_clear_rxhash(struct tpacket_kbdq_core *, struct tpacket3_hdr *); @@ -540,20 +537,14 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po, prb_del_retire_blk_timer(pkc); } -static void prb_init_blk_timer(struct packet_sock *po, - struct tpacket_kbdq_core *pkc, - void (*func) (unsigned long)) -{ - setup_timer(&pkc->retire_blk_timer, func, (long)po); - pkc->retire_blk_timer.expires = jiffies; -} - static void prb_setup_retire_blk_timer(struct packet_sock *po) { struct tpacket_kbdq_core *pkc; pkc = GET_PBDQC_FROM_RB(&po->rx_ring); - prb_init_blk_timer(po, pkc, prb_retire_rx_blk_timer_expired); + timer_setup(&pkc->retire_blk_timer, prb_retire_rx_blk_timer_expired, + 0); + pkc->retire_blk_timer.expires = jiffies; } static int prb_calc_retire_blk_tmo(struct packet_sock *po, @@ -671,9 +662,10 @@ static void _prb_refresh_rx_retire_blk_timer(struct tpacket_kbdq_core *pkc) * prb_calc_retire_blk_tmo() calculates the tmo. * */ -static void prb_retire_rx_blk_timer_expired(unsigned long data) +static void prb_retire_rx_blk_timer_expired(struct timer_list *t) { - struct packet_sock *po = (struct packet_sock *)data; + struct packet_sock *po = + from_timer(po, t, rx_ring.prb_bdqc.retire_blk_timer); struct tpacket_kbdq_core *pkc = GET_PBDQC_FROM_RB(&po->rx_ring); unsigned int frozen; struct tpacket_block_desc *pbd; -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] net: dccp: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Adds a pointer back to the sock. Cc: Gerrit Renker Cc: "David S. Miller" Cc: Soheil Hassas Yeganeh Cc: Hannes Frederic Sowa Cc: Eric Dumazet Cc: d...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- net/dccp/ccids/ccid2.c | 10 +- net/dccp/ccids/ccid2.h | 1 + net/dccp/ccids/ccid3.c | 11 ++- net/dccp/ccids/ccid3.h | 1 + net/dccp/timer.c | 12 +++- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index e1295d5f2c56..1c75cd1255f6 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -126,10 +126,10 @@ static void ccid2_change_l_seq_window(struct sock *sk, u64 val) DCCPF_SEQ_WMAX)); } -static void ccid2_hc_tx_rto_expire(unsigned long data) +static void ccid2_hc_tx_rto_expire(struct timer_list *t) { - struct sock *sk = (struct sock *)data; - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); + struct ccid2_hc_tx_sock *hc = from_timer(hc, t, tx_rtotimer); + struct sock *sk = hc->sk; const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); bh_lock_sock(sk); @@ -733,8 +733,8 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) hc->tx_rpdupack = -1; hc->tx_last_cong = hc->tx_lsndtime = hc->tx_cwnd_stamp = ccid2_jiffies32; hc->tx_cwnd_used = 0; - setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, - (unsigned long)sk); + hc->sk = sk; + timer_setup(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, 0); INIT_LIST_HEAD(&hc->tx_av_chunks); return 0; } diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index 6e50ef2898fb..1af0116dc6ce 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h @@ -85,6 +85,7 @@ struct ccid2_hc_tx_sock { tx_rto; u64 tx_rtt_seq:48; struct timer_list tx_rtotimer; + struct sock *sk; /* Congestion Window validation (optional, RFC 2861) */ u32 tx_cwnd_used, diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 119c04317d48..8b5ba6dffac7 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -195,10 +195,10 @@ static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hc, } } -static void ccid3_hc_tx_no_feedback_timer(unsigned long data) +static void ccid3_hc_tx_no_feedback_timer(struct timer_list *t) { - struct sock *sk = (struct sock *)data; - struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); + struct ccid3_hc_tx_sock *hc = from_timer(hc, t, tx_no_feedback_timer); + struct sock *sk = hc->sk; unsigned long t_nfb = USEC_PER_SEC / 5; bh_lock_sock(sk); @@ -505,8 +505,9 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) hc->tx_state = TFRC_SSTATE_NO_SENT; hc->tx_hist = NULL; - setup_timer(&hc->tx_no_feedback_timer, - ccid3_hc_tx_no_feedback_timer, (unsigned long)sk); + hc->sk = sk; + timer_setup(&hc->tx_no_feedback_timer, + ccid3_hc_tx_no_feedback_timer, 0); return 0; } diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 1a9933c29672..813d91c6e1e2 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -106,6 +106,7 @@ struct ccid3_hc_tx_sock { u8 tx_last_win_count; ktime_t tx_t_last_win_count; struct timer_list tx_no_feedback_timer; + struct sock *sk; ktime_t tx_t_ld; ktime_t tx_t_nom; struct tfrc_tx_hist_entry *tx_hist; diff --git a/net/dccp/timer.c b/net/dccp/timer.c index 1e35526bf436..b50a8732ff43 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c @@ -234,10 +234,13 @@ static void dccp_write_xmitlet(unsigned long data) bh_unlock_sock(sk); } -static void dccp_write_xmit_timer(unsigned long data) +static void dccp_write_xmit_timer(struct timer_list *t) { - dccp_write_xmitlet(data); - sock_put((struct sock *)data); + struct dccp_sock *dp = from_timer(dp, t, dccps_xmit_timer); + struct sock *sk = &dp->dccps_inet_connection.icsk_inet.sk; + + dccp_write_xmitlet((unsigned long)sk); + sock_put(sk); } void dccp_init_xmit_timers(struct sock *sk) @@ -245,8 +248,7 @@ void dccp_init_xmit_timers(struct sock *sk) struct dccp_sock *dp = dccp_sk(sk); tasklet_init(&dp->dccps_xmitlet, dccp_write_xmitlet, (unsigned long)sk); - setup_timer(&dp->dc
[PATCH] net: ax25: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Joerg Reuter Cc: Ralf Baechle Cc: "David S. Miller" Cc: linux-h...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- net/ax25/af_ax25.c | 7 +++ net/ax25/ax25_ds_timer.c | 9 - net/ax25/ax25_timer.c| 41 - 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index f3f9d18891de..06eac1f50c5e 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -268,9 +268,9 @@ void ax25_destroy_socket(ax25_cb *); /* * Handler for deferred kills. */ -static void ax25_destroy_timer(unsigned long data) +static void ax25_destroy_timer(struct timer_list *t) { - ax25_cb *ax25=(ax25_cb *)data; + ax25_cb *ax25 = from_timer(ax25, t, dtimer); struct sock *sk; sk=ax25->sk; @@ -326,8 +326,7 @@ void ax25_destroy_socket(ax25_cb *ax25) if (ax25->sk != NULL) { if (sk_has_allocations(ax25->sk)) { /* Defer: outstanding buffers */ - setup_timer(&ax25->dtimer, ax25_destroy_timer, - (unsigned long)ax25); + timer_setup(&ax25->dtimer, ax25_destroy_timer, 0); ax25->dtimer.expires = jiffies + 2 * HZ; add_timer(&ax25->dtimer); } else { diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c index 5fb2104b7304..e9d11313d45b 100644 --- a/net/ax25/ax25_ds_timer.c +++ b/net/ax25/ax25_ds_timer.c @@ -29,7 +29,7 @@ #include #include -static void ax25_ds_timeout(unsigned long); +static void ax25_ds_timeout(struct timer_list *); /* * Add DAMA slave timeout timer to timer list. @@ -41,8 +41,7 @@ static void ax25_ds_timeout(unsigned long); void ax25_ds_setup_timer(ax25_dev *ax25_dev) { - setup_timer(&ax25_dev->dama.slave_timer, ax25_ds_timeout, - (unsigned long)ax25_dev); + timer_setup(&ax25_dev->dama.slave_timer, ax25_ds_timeout, 0); } void ax25_ds_del_timer(ax25_dev *ax25_dev) @@ -66,9 +65,9 @@ void ax25_ds_set_timer(ax25_dev *ax25_dev) * Silently discard all (slave) connections in case our master forgot us... */ -static void ax25_ds_timeout(unsigned long arg) +static void ax25_ds_timeout(struct timer_list *t) { - ax25_dev *ax25_dev = (struct ax25_dev *) arg; + ax25_dev *ax25_dev = from_timer(ax25_dev, t, dama.slave_timer); ax25_cb *ax25; if (ax25_dev == NULL || !ax25_dev->dama.slave) diff --git a/net/ax25/ax25_timer.c b/net/ax25/ax25_timer.c index 23a6f38a80bf..c47b7ee1e4da 100644 --- a/net/ax25/ax25_timer.c +++ b/net/ax25/ax25_timer.c @@ -33,20 +33,19 @@ #include #include -static void ax25_heartbeat_expiry(unsigned long); -static void ax25_t1timer_expiry(unsigned long); -static void ax25_t2timer_expiry(unsigned long); -static void ax25_t3timer_expiry(unsigned long); -static void ax25_idletimer_expiry(unsigned long); +static void ax25_heartbeat_expiry(struct timer_list *); +static void ax25_t1timer_expiry(struct timer_list *); +static void ax25_t2timer_expiry(struct timer_list *); +static void ax25_t3timer_expiry(struct timer_list *); +static void ax25_idletimer_expiry(struct timer_list *); void ax25_setup_timers(ax25_cb *ax25) { - setup_timer(&ax25->timer, ax25_heartbeat_expiry, (unsigned long)ax25); - setup_timer(&ax25->t1timer, ax25_t1timer_expiry, (unsigned long)ax25); - setup_timer(&ax25->t2timer, ax25_t2timer_expiry, (unsigned long)ax25); - setup_timer(&ax25->t3timer, ax25_t3timer_expiry, (unsigned long)ax25); - setup_timer(&ax25->idletimer, ax25_idletimer_expiry, - (unsigned long)ax25); + timer_setup(&ax25->timer, ax25_heartbeat_expiry, 0); + timer_setup(&ax25->t1timer, ax25_t1timer_expiry, 0); + timer_setup(&ax25->t2timer, ax25_t2timer_expiry, 0); + timer_setup(&ax25->t3timer, ax25_t3timer_expiry, 0); + timer_setup(&ax25->idletimer, ax25_idletimer_expiry, 0); } void ax25_start_heartbeat(ax25_cb *ax25) @@ -120,10 +119,10 @@ unsigned long ax25_display_timer(struct timer_list *timer) EXPORT_SYMBOL(ax25_display_timer); -static void ax25_heartbeat_expiry(unsigned long param) +static void ax25_heartbeat_expiry(struct timer_list *t) { int proto = AX25_PROTO_STD_SIMPLEX; - ax25_cb *ax25 = (ax25_cb *)param; + ax25_cb *ax25 = from_timer(ax25, t, timer); if (ax25->ax25_dev) proto = ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]; @@ -145,9 +144,9 @@ static void ax25_heartbeat_expiry(unsigned long param) } } -static void ax25_t1timer_expiry(unsigned long param) +static void ax25_t1timer_expiry(struct timer_list *t) { - ax25_cb *ax25 =
[PATCH] net: hsr: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Arvid Brodin Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- net/hsr/hsr_device.c | 9 - net/hsr/hsr_framereg.c | 6 ++ net/hsr/hsr_framereg.h | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 172d8309f89e..b8cd43c9ed5b 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -328,12 +328,12 @@ static void send_hsr_supervision_frame(struct hsr_port *master, /* Announce (supervision frame) timer function */ -static void hsr_announce(unsigned long data) +static void hsr_announce(struct timer_list *t) { struct hsr_priv *hsr; struct hsr_port *master; - hsr = (struct hsr_priv *) data; + hsr = from_timer(hsr, t, announce_timer); rcu_read_lock(); master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); @@ -463,9 +463,8 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], hsr->sequence_nr = HSR_SEQNR_START; hsr->sup_sequence_nr = HSR_SUP_SEQNR_START; - setup_timer(&hsr->announce_timer, hsr_announce, (unsigned long)hsr); - - setup_timer(&hsr->prune_timer, hsr_prune_nodes, (unsigned long)hsr); + timer_setup(&hsr->announce_timer, hsr_announce, 0); + timer_setup(&hsr->prune_timer, hsr_prune_nodes, 0); ether_addr_copy(hsr->sup_multicast_addr, def_multicast_addr); hsr->sup_multicast_addr[ETH_ALEN - 1] = multicast_spec; diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 284a9b820df8..286ceb41ac0c 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -365,16 +365,14 @@ static struct hsr_port *get_late_port(struct hsr_priv *hsr, /* Remove stale sequence_nr records. Called by timer every * HSR_LIFE_CHECK_INTERVAL (two seconds or so). */ -void hsr_prune_nodes(unsigned long data) +void hsr_prune_nodes(struct timer_list *t) { - struct hsr_priv *hsr; + struct hsr_priv *hsr = from_timer(hsr, t, prune_timer); struct hsr_node *node; struct hsr_port *port; unsigned long timestamp; unsigned long time_a, time_b; - hsr = (struct hsr_priv *) data; - rcu_read_lock(); list_for_each_entry_rcu(node, &hsr->node_db, mac_list) { /* Shorthand */ diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h index 4e04f0e868e9..370b45998121 100644 --- a/net/hsr/hsr_framereg.h +++ b/net/hsr/hsr_framereg.h @@ -33,7 +33,7 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port, int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node, u16 sequence_nr); -void hsr_prune_nodes(unsigned long data); +void hsr_prune_nodes(struct timer_list *t); int hsr_create_self_node(struct list_head *self_node_db, unsigned char addr_a[ETH_ALEN], -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] net: ethernet/sfc: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Solarflare linux maintainers Cc: Edward Cree Cc: Bert Kenward Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jiri Pirko Cc: Jamal Hadi Salim Cc: Ingo Molnar Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/ethernet/sfc/efx.c | 6 ++ drivers/net/ethernet/sfc/efx.h | 2 +- drivers/net/ethernet/sfc/falcon/efx.c| 6 ++ drivers/net/ethernet/sfc/falcon/efx.h| 2 +- drivers/net/ethernet/sfc/falcon/falcon.c | 11 ++- drivers/net/ethernet/sfc/falcon/nic.h| 2 ++ drivers/net/ethernet/sfc/falcon/rx.c | 4 ++-- drivers/net/ethernet/sfc/mcdi.c | 9 - drivers/net/ethernet/sfc/rx.c| 4 ++-- 9 files changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index b9cb697b2818..8fdcf7aaf997 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -471,8 +471,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) rx_queue = &channel->rx_queue; rx_queue->efx = efx; - setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, - (unsigned long)rx_queue); + timer_setup(&rx_queue->slow_fill, efx_rx_slow_fill, 0); return channel; } @@ -511,8 +510,7 @@ efx_copy_channel(const struct efx_channel *old_channel) rx_queue = &channel->rx_queue; rx_queue->buffer = NULL; memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd)); - setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, - (unsigned long)rx_queue); + timer_setup(&rx_queue->slow_fill, efx_rx_slow_fill, 0); return channel; } diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index d407adf59610..52c84b782901 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -46,7 +46,7 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); void efx_init_rx_queue(struct efx_rx_queue *rx_queue); void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic); -void efx_rx_slow_fill(unsigned long context); +void efx_rx_slow_fill(struct timer_list *t); void __efx_rx_packet(struct efx_channel *channel); void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int n_frags, unsigned int len, u16 flags); diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c index 29614da91cbf..6685a66ee1a3 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.c +++ b/drivers/net/ethernet/sfc/falcon/efx.c @@ -449,8 +449,7 @@ ef4_alloc_channel(struct ef4_nic *efx, int i, struct ef4_channel *old_channel) rx_queue = &channel->rx_queue; rx_queue->efx = efx; - setup_timer(&rx_queue->slow_fill, ef4_rx_slow_fill, - (unsigned long)rx_queue); + timer_setup(&rx_queue->slow_fill, ef4_rx_slow_fill, 0); return channel; } @@ -489,8 +488,7 @@ ef4_copy_channel(const struct ef4_channel *old_channel) rx_queue = &channel->rx_queue; rx_queue->buffer = NULL; memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd)); - setup_timer(&rx_queue->slow_fill, ef4_rx_slow_fill, - (unsigned long)rx_queue); + timer_setup(&rx_queue->slow_fill, ef4_rx_slow_fill, 0); return channel; } diff --git a/drivers/net/ethernet/sfc/falcon/efx.h b/drivers/net/ethernet/sfc/falcon/efx.h index 4f3bb30661ea..a4e4d8ea4078 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.h +++ b/drivers/net/ethernet/sfc/falcon/efx.h @@ -45,7 +45,7 @@ void ef4_remove_rx_queue(struct ef4_rx_queue *rx_queue); void ef4_init_rx_queue(struct ef4_rx_queue *rx_queue); void ef4_fini_rx_queue(struct ef4_rx_queue *rx_queue); void ef4_fast_push_rx_descriptors(struct ef4_rx_queue *rx_queue, bool atomic); -void ef4_rx_slow_fill(unsigned long context); +void ef4_rx_slow_fill(struct timer_list *t); void __ef4_rx_packet(struct ef4_channel *channel); void ef4_rx_packet(struct ef4_rx_queue *rx_queue, unsigned int index, unsigned int n_frags, unsigned int len, u16 flags); diff --git a/drivers/net/ethernet/sfc/falcon/falcon.c b/drivers/net/ethernet/sfc/falcon/falcon.c index 93c713c1f627..ccda017b6794 100644 --- a/drivers/net/ethernet/sfc/falcon/falcon.c +++ b/drivers/net/ethernet/sfc/falcon/falcon.c @@ -1454,10 +1454,11 @@ static void falcon_stats_complete(struct ef4_nic *efx) } } -static void falcon_stats_timer_func(unsigned long context) +static void falcon_stats_timer_func(struct timer_list *t) { - struct ef4_nic *efx = (struct ef4_nic *)context; - struct falcon_nic_data *nic_data = efx->nic_data; + struct
[PATCH] net: LLC: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: "David S. Miller" Cc: Eric Dumazet Cc: Hans Liljestrand Cc: "Paul E. McKenney" Cc: "Reshetova, Elena" Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- include/net/llc_c_ac.h | 8 net/llc/llc_c_ac.c | 27 +-- net/llc/llc_conn.c | 12 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h index f3be818e73c1..e766300b3e99 100644 --- a/include/net/llc_c_ac.h +++ b/include/net/llc_c_ac.h @@ -171,10 +171,10 @@ int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb); int llc_conn_ac_send_i_rsp_as_ack(struct sock *sk, struct sk_buff *skb); int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb); -void llc_conn_busy_tmr_cb(unsigned long timeout_data); -void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data); -void llc_conn_ack_tmr_cb(unsigned long timeout_data); -void llc_conn_rej_tmr_cb(unsigned long timeout_data); +void llc_conn_busy_tmr_cb(struct timer_list *t); +void llc_conn_pf_cycle_tmr_cb(struct timer_list *t); +void llc_conn_ack_tmr_cb(struct timer_list *t); +void llc_conn_rej_tmr_cb(struct timer_list *t); void llc_conn_set_p_flag(struct sock *sk, u8 value); #endif /* LLC_C_AC_H */ diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index ea225bd2672c..f59648018060 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -1318,9 +1318,8 @@ static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb) return 0; } -static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type) +static void llc_conn_tmr_common_cb(struct sock *sk, u8 type) { - struct sock *sk = (struct sock *)timeout_data; struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); bh_lock_sock(sk); @@ -1334,24 +1333,32 @@ static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type) bh_unlock_sock(sk); } -void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) +void llc_conn_pf_cycle_tmr_cb(struct timer_list *t) { - llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR); + struct llc_sock *llc = from_timer(llc, t, pf_cycle_timer.timer); + + llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_P_TMR); } -void llc_conn_busy_tmr_cb(unsigned long timeout_data) +void llc_conn_busy_tmr_cb(struct timer_list *t) { - llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR); + struct llc_sock *llc = from_timer(llc, t, busy_state_timer.timer); + + llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_BUSY_TMR); } -void llc_conn_ack_tmr_cb(unsigned long timeout_data) +void llc_conn_ack_tmr_cb(struct timer_list *t) { - llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR); + struct llc_sock *llc = from_timer(llc, t, ack_timer.timer); + + llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_ACK_TMR); } -void llc_conn_rej_tmr_cb(unsigned long timeout_data) +void llc_conn_rej_tmr_cb(struct timer_list *t) { - llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR); + struct llc_sock *llc = from_timer(llc, t, rej_sent_timer.timer); + + llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_REJ_TMR); } int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb) diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 5e91b47f0d2a..9177dbb16dce 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -902,20 +902,16 @@ static void llc_sk_init(struct sock *sk) llc->inc_cntr = llc->dec_cntr = 2; llc->dec_step = llc->connect_step = 1; - setup_timer(&llc->ack_timer.timer, llc_conn_ack_tmr_cb, - (unsigned long)sk); + timer_setup(&llc->ack_timer.timer, llc_conn_ack_tmr_cb, 0); llc->ack_timer.expire = sysctl_llc2_ack_timeout; - setup_timer(&llc->pf_cycle_timer.timer, llc_conn_pf_cycle_tmr_cb, - (unsigned long)sk); + timer_setup(&llc->pf_cycle_timer.timer, llc_conn_pf_cycle_tmr_cb, 0); llc->pf_cycle_timer.expire = sysctl_llc2_p_timeout; - setup_timer(&llc->rej_sent_timer.timer, llc_conn_rej_tmr_cb, - (unsigned long)sk); + timer_setup(&llc->rej_sent_timer.timer, llc_conn_rej_tmr_cb, 0); llc->rej_sent_timer.expire = sysctl_llc2_rej_timeout; - setup_timer(&llc->busy_state_timer.timer, llc_conn_busy_tmr_cb, - (unsigned long)sk); + timer_setup(&llc->busy_state_timer.timer, llc_conn_busy_tmr_cb, 0); llc->busy_state_timer.expire = sysctl_llc2_busy_timeout; llc->n2 = 2; /* max retransmit */ -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] net: sctp: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Vlad Yasevich Cc: Neil Horman Cc: "David S. Miller" Cc: linux-s...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- include/net/sctp/sm.h| 10 +++--- net/sctp/associola.c | 3 +- net/sctp/protocol.c | 7 ++-- net/sctp/sm_sideeffect.c | 85 +--- net/sctp/transport.c | 13 +++- 5 files changed, 66 insertions(+), 52 deletions(-) diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 2db3d3a9ce1d..13cc4963e905 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -72,7 +72,7 @@ typedef enum sctp_disposition (sctp_state_fn_t) ( const union sctp_subtype type, void *arg, struct sctp_cmd_seq *commands); -typedef void (sctp_timer_event_t) (unsigned long); +typedef void (sctp_timer_event_t) (struct timer_list *); struct sctp_sm_table_entry { sctp_state_fn_t *fn; const char *name; @@ -314,10 +314,10 @@ int sctp_do_sm(struct net *net, enum sctp_event event_type, void *event_arg, gfp_t gfp); /* 2nd level prototypes */ -void sctp_generate_t3_rtx_event(unsigned long peer); -void sctp_generate_heartbeat_event(unsigned long peer); -void sctp_generate_reconf_event(unsigned long peer); -void sctp_generate_proto_unreach_event(unsigned long peer); +void sctp_generate_t3_rtx_event(struct timer_list *t); +void sctp_generate_heartbeat_event(struct timer_list *t); +void sctp_generate_reconf_event(struct timer_list *t); +void sctp_generate_proto_unreach_event(struct timer_list *t); void sctp_ootb_pkt_free(struct sctp_packet *packet); diff --git a/net/sctp/associola.c b/net/sctp/associola.c index dfb9651e818b..69394f4d6091 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -149,8 +149,7 @@ static struct sctp_association *sctp_association_init( /* Initializes the timers */ for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) - setup_timer(&asoc->timers[i], sctp_timer_events[i], - (unsigned long)asoc); + timer_setup(&asoc->timers[i], sctp_timer_events[i], 0); /* Pull default initialization values from the sock options. * Note: This assumes that the values have already been diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index fcd80feb293f..f5172c21349b 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -622,9 +622,9 @@ static void sctp_v4_ecn_capable(struct sock *sk) INET_ECN_xmit(sk); } -static void sctp_addr_wq_timeout_handler(unsigned long arg) +static void sctp_addr_wq_timeout_handler(struct timer_list *t) { - struct net *net = (struct net *)arg; + struct net *net = from_timer(net, t, sctp.addr_wq_timer); struct sctp_sockaddr_entry *addrw, *temp; struct sctp_sock *sp; @@ -1304,8 +1304,7 @@ static int __net_init sctp_defaults_init(struct net *net) INIT_LIST_HEAD(&net->sctp.auto_asconf_splist); spin_lock_init(&net->sctp.addr_wq_lock); net->sctp.addr_wq_timer.expires = 0; - setup_timer(&net->sctp.addr_wq_timer, sctp_addr_wq_timeout_handler, - (unsigned long)net); + timer_setup(&net->sctp.addr_wq_timer, sctp_addr_wq_timeout_handler, 0); return 0; diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 402bfbb888cd..1c2699b424af 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -243,9 +243,10 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, /* When the T3-RTX timer expires, it calls this function to create the * relevant state machine event. */ -void sctp_generate_t3_rtx_event(unsigned long peer) +void sctp_generate_t3_rtx_event(struct timer_list *t) { - struct sctp_transport *transport = (struct sctp_transport *) peer; + struct sctp_transport *transport = + from_timer(transport, t, T3_rtx_timer); struct sctp_association *asoc = transport->asoc; struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); @@ -319,50 +320,63 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc, sctp_association_put(asoc); } -static void sctp_generate_t1_cookie_event(unsigned long data) +static void sctp_generate_t1_cookie_event(struct timer_list *t) { - struct sctp_association *asoc = (struct sctp_association *) data; + struct sctp_association *asoc = + from_timer(asoc, t, timers[SCTP_EVENT_TIMEOUT_T1_COOKIE]); + sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_COOKIE); } -static void sctp_generate_t1_init_event(unsigned long data) +static void sctp_gen
Re: [PATCH net-next 0/7] ipv6: addrconf: hash improvements and cleanups
From: Eric Dumazet Date: Mon, 23 Oct 2017 16:17:44 -0700 > Remove unecessary BH blocking, and bring IPv6 addrconf to modern world, > with per netns hash perturbation and decent hash size. Series applied.
Re: problem with rtnetlink 'reference' count
Peter Zijlstra wrote: > On Mon, Oct 23, 2017 at 09:37:03PM +0200, Florian Westphal wrote: > > > > OK, so then why not do something like so? > > > @@ -260,10 +259,18 @@ void rtnl_unregister_all(int protocol) > > > RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); > > > rtnl_unlock(); > > > > > > + /* > > > + * XXX explain what this is for... > > > + */ > > > synchronize_net(); > > > > > > - while (refcount_read(&rtnl_msg_handlers_ref[protocol]) > 1) > > > - schedule(); > > > + /* > > > + * This serializes against the rcu_read_lock() section in > > > + * rtnetlink_rcv_msg() such that after this, all prior instances have > > > + * completed and future instances must observe the NULL written above. > > > + */ > > > + synchronize_rcu(); > > > > Yes, but that won't help with running dumpers, see below. > > > > > @@ -4218,7 +4223,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, > > > struct nlmsghdr *nlh, > > > }; > > > err = netlink_dump_start(rtnl, skb, nlh, &c); > > > > This will copy .dumper function address to nlh->cb for later invocation > > when dump gets resumed (its called from netlink_recvmsg()), > > so this can return to userspace and dump can be resumed on next recv(). > > > > Because the dumper function was stored in the socket, NULLing the > > rtnl_msg_handlers[] only prevents new dumps from starting but not > > already set-up dumps from resuming. > > but netlink_dump_start() will actually grab a reference on the module; > but it does so too late. Yes, but rtnl_register() doesn't pass a module pointer, i.e. in rtnetlink_rcv_msg we can't set up the module pointer to the correct one. We'd have to pass the module pointer to rtnl_register() and store it, or add a new api that passes it, or, yet another option, avoid use of .dumpit from modular users and keep the dump handling fully within these modules. (the api is from ancient times when it was only used from builtin code paths). I'll try a few things tomorrow to see what makes most sense or if there are any other options.
[patch net-next 3/3] mlxsw: spectrum: mr_tcam: Include the mr_tcam header file
From: Yotam Gigi Make the spectrum_mr_tcam.c include the spectrum_mr_tcam.h header file. Cleans up sparse warning: symbol 'mlxsw_sp_mr_tcam_ops' was not declared. Should it be static? Fixes: 0e14cacb6 ("mlxsw: spectrum: Add the multicast routing hardware logic") Signed-off-by: Yotam Gigi Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c index 39c21c7..34a0b63 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c @@ -37,6 +37,7 @@ #include #include +#include "spectrum_mr_tcam.h" #include "reg.h" #include "spectrum.h" #include "core_acl_flex_actions.h" -- 2.9.5
[patch net-next 2/3] mlxsw: spectrum: mr: Make the function mlxsw_sp_mr_dev_vif_lookup static
From: Yotam Gigi The function is only used internally in spectrum_mr.c and is not declared in the header file, thus make it static. Cleans up sparse warning: symbol 'mlxsw_sp_mr_dev_vif_lookup' was not declared. Should it be static? Fixes: c011ec1bbfd6 ("mlxsw: spectrum: Add the multicast routing offloading logic") Signed-off-by: Yotam Gigi Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c index 3f7d2d1..d20b143 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c @@ -768,7 +768,7 @@ void mlxsw_sp_mr_vif_del(struct mlxsw_sp_mr_table *mr_table, vifi_t vif_index) mlxsw_sp_mr_vif_unresolve(mr_table, NULL, mr_vif); } -struct mlxsw_sp_mr_vif * +static struct mlxsw_sp_mr_vif * mlxsw_sp_mr_dev_vif_lookup(struct mlxsw_sp_mr_table *mr_table, const struct net_device *dev) { -- 2.9.5
[patch net-next 1/3] mlxsw: spectrum: mr: Fix various endianness issues
From: Yotam Gigi Fix various endianness issues in comparisons and assignments. The fix is entirely cosmetic as all the values fixed are endianness-agnostic. Cleans up sparse warnings: spectrum_mr.c:156:49: warning: restricted __be32 degrades to integer spectrum_mr.c:206:26: warning: restricted __be32 degrades to integer spectrum_mr.c:212:31: warning: incorrect type in assignment (different base types) spectrum_mr.c:212:31:expected restricted __be32 [usertype] addr4 spectrum_mr.c:212:31:got unsigned int spectrum_mr.c:214:32: warning: incorrect type in assignment (different base types) spectrum_mr.c:214:32:expected restricted __be32 [usertype] addr4 spectrum_mr.c:214:32:got unsigned int spectrum_mr.c:461:16: warning: restricted __be32 degrades to integer spectrum_mr.c:461:49: warning: restricted __be32 degrades to integer Fixes: c011ec1bbfd6 ("mlxsw: spectrum: Add the multicast routing offloading logic") Signed-off-by: Yotam Gigi Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c index 1f84bb8..3f7d2d1 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c @@ -153,7 +153,7 @@ static bool mlxsw_sp_mr_route_starg(const struct mlxsw_sp_mr_route *mr_route) { switch (mr_route->mr_table->proto) { case MLXSW_SP_L3_PROTO_IPV4: - return mr_route->key.source_mask.addr4 == INADDR_ANY; + return mr_route->key.source_mask.addr4 == htonl(INADDR_ANY); case MLXSW_SP_L3_PROTO_IPV6: /* fall through */ default: @@ -203,15 +203,15 @@ static void mlxsw_sp_mr_route4_key(struct mlxsw_sp_mr_table *mr_table, struct mlxsw_sp_mr_route_key *key, const struct mfc_cache *mfc) { - bool starg = (mfc->mfc_origin == INADDR_ANY); + bool starg = (mfc->mfc_origin == htonl(INADDR_ANY)); memset(key, 0, sizeof(*key)); key->vrid = mr_table->vr_id; key->proto = mr_table->proto; key->group.addr4 = mfc->mfc_mcastgrp; - key->group_mask.addr4 = 0x; + key->group_mask.addr4 = htonl(0x); key->source.addr4 = mfc->mfc_origin; - key->source_mask.addr4 = starg ? 0 : 0x; + key->source_mask.addr4 = htonl(starg ? 0 : 0x); } static int mlxsw_sp_mr_route_evif_link(struct mlxsw_sp_mr_route *mr_route, @@ -458,7 +458,8 @@ int mlxsw_sp_mr_route4_add(struct mlxsw_sp_mr_table *mr_table, /* If the route is a (*,*) route, abort, as these kind of routes are * used for proxy routes. */ - if (mfc->mfc_origin == INADDR_ANY && mfc->mfc_mcastgrp == INADDR_ANY) { + if (mfc->mfc_origin == htonl(INADDR_ANY) && + mfc->mfc_mcastgrp == htonl(INADDR_ANY)) { dev_warn(mr_table->mlxsw_sp->bus_info->dev, "Offloading proxy routes is not supported.\n"); return -EINVAL; -- 2.9.5
[patch net-next 0/3] mlxsw: Various fixes
From: Jiri Pirko Yotam says: Cleanup some issues reported by sparse. Yotam Gigi (3): mlxsw: spectrum: mr: Fix various endianness issues mlxsw: spectrum: mr: Make the function mlxsw_sp_mr_dev_vif_lookup static mlxsw: spectrum: mr_tcam: Include the mr_tcam header file drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 13 +++-- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) -- 2.9.5
Re: [PATCH net-next 0/2] net: dsa: don't unmask port bitmaps
> In case of probe deferral, you get the full probe function to exit with > an error, and that usually involves freeing the recently allocated > dsa_switch instance, and then allocating a new one when probe is > re-entered, so that should not be a problem. Hi Florian That is the simple case. I remember having problems with more complex cases, D in DSA. Switches 1 and 2 probe O.K, switch 3 fail with EPROBE_DEFER. Switch 3, as you say, releases its dsa_switch instance, so will get a freshly zero'ed new instance when it probes again. However, switches 1 and 2 only experience the unwind at the DSA level. The devices are not removed and later probed again. They have a 'dirty' dsa_switch structure the next time they are applied. I just think there might be potential for regressions here. But i've not yet looked at the details to really know if there actually is. Andrew
[patch net-next RFC 2/7] devlink: Add per devlink instance lock
From: Arkadi Sharshevsky This is a preparation before introducing hot reload support. Currently there is one global lock protecting all devlink access. This patch adds per devlink instance lock which protects the internal members which are the sb/dpipe/resources. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- include/net/devlink.h | 1 + net/core/devlink.c| 50 +++--- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/include/net/devlink.h b/include/net/devlink.h index fe57534..789e606 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -31,6 +31,7 @@ struct devlink { const struct devlink_ops *ops; struct device *dev; possible_net_t _net; + struct mutex lock; char priv[0] __aligned(NETDEV_ALIGN); }; diff --git a/net/core/devlink.c b/net/core/devlink.c index a48dcd6..86dfec9 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -336,6 +336,8 @@ devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb, #define DEVLINK_NL_FLAG_NEED_PORT BIT(1) #define DEVLINK_NL_FLAG_NEED_SBBIT(2) #define DEVLINK_NL_FLAG_LOCK_PORTS BIT(3) +#define DEVLINK_NL_FLAG_NO_LOCKBIT(4) + /* port is not needed but we need to ensure they don't * change in the middle of command */ @@ -380,15 +382,24 @@ static int devlink_nl_pre_doit(const struct genl_ops *ops, } info->user_ptr[1] = devlink_sb; } + if (!(ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)) + mutex_lock(&devlink->lock); + return 0; } static void devlink_nl_post_doit(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info) { + struct devlink *devlink; + + devlink = devlink_get_from_info(info); + if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT || ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) mutex_unlock(&devlink_port_mutex); + if (!(ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)) + mutex_unlock(&devlink->lock); mutex_unlock(&devlink_mutex); } @@ -801,6 +812,7 @@ static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, list_for_each_entry(devlink, &devlink_list, list) { if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) continue; + mutex_lock(&devlink->lock); list_for_each_entry(devlink_sb, &devlink->sb_list, list) { if (idx < start) { idx++; @@ -811,10 +823,13 @@ static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI); - if (err) + if (err) { + mutex_unlock(&devlink->lock); goto out; + } idx++; } + mutex_unlock(&devlink->lock); } out: mutex_unlock(&devlink_mutex); @@ -935,14 +950,18 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || !devlink->ops || !devlink->ops->sb_pool_get) continue; + mutex_lock(&devlink->lock); list_for_each_entry(devlink_sb, &devlink->sb_list, list) { err = __sb_pool_get_dumpit(msg, start, &idx, devlink, devlink_sb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq); - if (err && err != -EOPNOTSUPP) + if (err && err != -EOPNOTSUPP) { + mutex_unlock(&devlink->lock); goto out; + } } + mutex_unlock(&devlink->lock); } out: mutex_unlock(&devlink_mutex); @@ -2695,6 +2714,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) INIT_LIST_HEAD(&devlink->sb_list); INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); INIT_LIST_HEAD(&devlink->resource_list); + mutex_init(&devlink->lock); return devlink; } EXPORT_SYMBOL_GPL(devlink_alloc); @@ -2858,7 +2878,7 @@ int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, struct devlink_sb *devlink_sb; int err = 0; - mutex_lock(&devlink_mutex); + mutex_lock(&devlink->lock); if (devlink_sb_index_exists(devlink, sb_index)) {
[patch net-next RFC 0/7] Add support for resource abstraction
From: Jiri Pirko Arkadi says: Many of the ASIC's internal resources are limited and are shared between several hardware procedures. For example, unified hash-based memory can be used for many lookup purposes, like FDB and LPM. In many cases the user can provide a partitioning scheme for such a resource in order to perform fine tuning for his application. In many cases after setting the partitioning of the resource driver reload is needed. This patchset add support for hot reset of the driver. The proposed interface will provide the user the ability to understand the limitations of the hardware, and receive notification regarding its occupancy. Furthermore, monitoring the resource occupancy can be done in real-time and can be useful in many cases. Arkadi Sharshevsky (7): devlink: Add support for resource abstraction devlink: Add per devlink instance lock devlink: Add support for reload mlxsw: pci: Add support for performing bus reset mlxsw: Register KVD resources with devlink mlxsw: pci: Add support for getting resource through devlink mlxsw: core: Add support for reload drivers/net/ethernet/mellanox/mlxsw/core.c | 79 - drivers/net/ethernet/mellanox/mlxsw/core.h | 15 +- drivers/net/ethernet/mellanox/mlxsw/i2c.c | 4 +- drivers/net/ethernet/mellanox/mlxsw/pci.c | 100 --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 148 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 12 + include/net/devlink.h | 76 + include/uapi/linux/devlink.h | 9 + net/core/devlink.c | 385 - 9 files changed, 752 insertions(+), 76 deletions(-) -- 2.9.5
[patch net-next RFC 3/7] devlink: Add support for reload
From: Arkadi Sharshevsky Add support for performing driver hot reload. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- include/net/devlink.h| 1 + include/uapi/linux/devlink.h | 1 + net/core/devlink.c | 18 ++ 3 files changed, 20 insertions(+) diff --git a/include/net/devlink.h b/include/net/devlink.h index 789e606..ff6e384 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -263,6 +263,7 @@ struct devlink_resource { #define DEVLINK_RESOURCE_ID_PARENT_TOP 0 struct devlink_ops { + int (*reload)(struct devlink *devlink); int (*port_type_set)(struct devlink_port *devlink_port, enum devlink_port_type port_type); int (*port_split)(struct devlink *devlink, unsigned int port_index, diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 9db1d70..86a329a 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -71,6 +71,7 @@ enum devlink_command { DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, DEVLINK_CMD_RESOURCE_SET, DEVLINK_CMD_RESOURCE_DUMP, + DEVLINK_CMD_RELOAD, /* add new commands above here */ __DEVLINK_CMD_MAX, diff --git a/net/core/devlink.c b/net/core/devlink.c index 86dfec9..3a9fcda 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -2484,6 +2484,16 @@ static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); } +static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) +{ + struct devlink *devlink = info->user_ptr[0]; + + if (!devlink->ops->reload) + return -EOPNOTSUPP; + + return devlink->ops->reload(devlink); +} + static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, @@ -2676,6 +2686,14 @@ static const struct genl_ops devlink_nl_ops[] = { .flags = GENL_ADMIN_PERM, .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, }, + { + .cmd = DEVLINK_CMD_RELOAD, + .doit = devlink_nl_cmd_reload, + .policy = devlink_nl_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | + DEVLINK_NL_FLAG_NO_LOCK, + }, }; static struct genl_family devlink_nl_family __ro_after_init = { -- 2.9.5
[patch net-next RFC 4/7] mlxsw: pci: Add support for performing bus reset
From: Arkadi Sharshevsky This is a preparation stage before introducing hot reload. During the reload process the ASIC should be resetted by accessing the PCI BAR due to unavailability of the mailbox/emad interfaces. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/core.h | 1 + drivers/net/ethernet/mellanox/mlxsw/pci.c | 56 +++--- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index 6e966af..34dda96 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -332,6 +332,7 @@ struct mlxsw_bus { const struct mlxsw_config_profile *profile, struct mlxsw_res *res); void (*fini)(void *bus_priv); + void (*reset)(void *bus_priv); bool (*skb_transmit_busy)(void *bus_priv, const struct mlxsw_tx_info *tx_info); int (*skb_transmit)(void *bus_priv, struct sk_buff *skb, diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 23f7d82..00c9155 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -154,6 +154,7 @@ struct mlxsw_pci { } comp; } cmd; struct mlxsw_bus_info bus_info; + const struct pci_device_id *id; }; static void mlxsw_pci_queue_tasklet_schedule(struct mlxsw_pci_queue *q) @@ -1622,16 +1623,6 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod, return err; } -static const struct mlxsw_bus mlxsw_pci_bus = { - .kind = "pci", - .init = mlxsw_pci_init, - .fini = mlxsw_pci_fini, - .skb_transmit_busy = mlxsw_pci_skb_transmit_busy, - .skb_transmit = mlxsw_pci_skb_transmit, - .cmd_exec = mlxsw_pci_cmd_exec, - .features = MLXSW_BUS_F_TXRX, -}; - static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id) { @@ -1655,6 +1646,44 @@ static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, return 0; } +static void mlxsw_pci_free_irq_vectors(struct mlxsw_pci *mlxsw_pci) +{ + pci_free_irq_vectors(mlxsw_pci->pdev); +} + +static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci) +{ + int err; + + err = pci_alloc_irq_vectors(mlxsw_pci->pdev, 1, 1, PCI_IRQ_MSIX); + if (err < 0) { + dev_err(&mlxsw_pci->pdev->dev, "MSI-X init failed\n"); + return err; + } + + return 0; +} + +static void mlxsw_pci_reset(void *bus_priv) +{ + struct mlxsw_pci *mlxsw_pci = bus_priv; + + mlxsw_pci_free_irq_vectors(mlxsw_pci); + mlxsw_pci_sw_reset(mlxsw_pci, mlxsw_pci->id); + mlxsw_pci_alloc_irq_vectors(mlxsw_pci); +} + +static const struct mlxsw_bus mlxsw_pci_bus = { + .kind = "pci", + .init = mlxsw_pci_init, + .fini = mlxsw_pci_fini, + .skb_transmit_busy = mlxsw_pci_skb_transmit_busy, + .skb_transmit = mlxsw_pci_skb_transmit, + .cmd_exec = mlxsw_pci_cmd_exec, + .features = MLXSW_BUS_F_TXRX, + .reset = mlxsw_pci_reset, +}; + static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { const char *driver_name = pdev->driver->name; @@ -1716,7 +1745,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_sw_reset; } - err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX); + err = mlxsw_pci_alloc_irq_vectors(mlxsw_pci); if (err < 0) { dev_err(&pdev->dev, "MSI-X init failed\n"); goto err_msix_init; @@ -1725,6 +1754,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) mlxsw_pci->bus_info.device_kind = driver_name; mlxsw_pci->bus_info.device_name = pci_name(mlxsw_pci->pdev); mlxsw_pci->bus_info.dev = &pdev->dev; + mlxsw_pci->id = id; err = mlxsw_core_bus_device_register(&mlxsw_pci->bus_info, &mlxsw_pci_bus, mlxsw_pci); @@ -1736,7 +1766,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; err_bus_device_register: - pci_free_irq_vectors(mlxsw_pci->pdev); + mlxsw_pci_free_irq_vectors(mlxsw_pci); err_msix_init: err_sw_reset: iounmap(mlxsw_pci->hw_addr); @@ -1756,7 +1786,7 @@ static void mlxsw_pci_remove(struct pci_dev *pdev) struct mlxsw_pci *mlxsw_pci = pci_get_drvdata(pdev); mlxsw_core_bus_device_unregister(mlxsw_pci->core);
[patch net-next RFC 5/7] mlxsw: Register KVD resources with devlink
From: Arkadi Sharshevsky Register the KVD resources with devlink. The KVD is a memory resource which is subdivided into three partitions which are the linear, hash single and hash double. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/core.c | 9 +++ drivers/net/ethernet/mellanox/mlxsw/core.h | 1 + drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 91 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 12 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index f3315bc..ee41036 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -1012,6 +1012,12 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, if (err) goto err_bus_init; + if (mlxsw_driver->resources_register) { + err = mlxsw_driver->resources_register(mlxsw_core); + if (err) + goto err_register_resources; + } + err = mlxsw_ports_init(mlxsw_core); if (err) goto err_ports_init; @@ -1067,6 +1073,8 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, err_ports_init: mlxsw_bus->fini(bus_priv); err_bus_init: + devlink_resources_clear(devlink); +err_register_resources: devlink_free(devlink); err_devlink_alloc: mlxsw_core_driver_put(device_kind); @@ -1086,6 +1094,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core) mlxsw_emad_fini(mlxsw_core); kfree(mlxsw_core->lag.mapping); mlxsw_ports_fini(mlxsw_core); + devlink_resources_clear(devlink); mlxsw_core->bus->fini(mlxsw_core->bus_priv); devlink_free(devlink); mlxsw_core_driver_put(device_kind); diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index 34dda96..e23f83b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -308,6 +308,7 @@ struct mlxsw_driver { u32 *p_cur, u32 *p_max); void (*txhdr_construct)(struct sk_buff *skb, const struct mlxsw_tx_info *tx_info); + int (*resources_register)(struct mlxsw_core *mlxsw_core); u8 txhdr_len; const struct mlxsw_config_profile *profile; }; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 12b6ac4..565f94e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -3864,7 +3864,6 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) mlxsw_sp_fids_fini(mlxsw_sp); mlxsw_sp_kvdl_fini(mlxsw_sp); } - static const struct mlxsw_config_profile mlxsw_sp_config_profile = { .used_max_vepa_channels = 1, .max_vepa_channels = 0, @@ -3897,6 +3896,95 @@ static const struct mlxsw_config_profile mlxsw_sp_config_profile = { .resource_query_enable = 1, }; +int mlxsw_sp_resource_kvd_size_validate(void *priv, u64 size) +{ + /* KVD total size cannot be set*/ + return -EINVAL; +} + +int mlxsw_sp_resource_kvd_sub_size_validate(void *priv, u64 size) +{ + const struct mlxsw_config_profile *profile; + + profile = &mlxsw_sp_config_profile; + if (size % profile->kvd_hash_granularity) + return -EINVAL; + return 0; +} + +static struct devlink_resource_ops mlxsw_sp_resource_kvd_ops = { + .size_validate = mlxsw_sp_resource_kvd_size_validate, +}; + +static struct devlink_resource_ops mlxsw_sp_resource_kvd_linear_ops = { + .size_validate = mlxsw_sp_resource_kvd_sub_size_validate, +}; + +static struct devlink_resource_ops mlxsw_sp_resource_kvd_hash_single_ops = { + .size_validate = mlxsw_sp_resource_kvd_sub_size_validate, +}; + +static struct devlink_resource_ops mlxsw_sp_resource_kvd_hash_double_ops = { + .size_validate = mlxsw_sp_resource_kvd_sub_size_validate, +}; + +static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core) +{ + struct devlink *devlink = priv_to_devlink(mlxsw_core); + u64 kvd_size, single_size, double_size, linear_size; + const struct mlxsw_config_profile *profile; + int err; + + profile = &mlxsw_sp_config_profile; + if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE)) + return -EIO; + + kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE); + err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD, + true, kvd_size, + MLXSW_SP_RESOURCE_KVD, + DEVLINK_RESOURCE_ID_PARENT_TOP, +
[patch net-next RFC 7/7] mlxsw: core: Add support for reload
From: Arkadi Sharshevsky Add support for hot reload. First, all the driver/core resources are released but the PCI and devlink instances, then reset is performed through the PCI interface. Finally the driver performs initialization. In case of reload failure the driver is left in a partially initialized state. Special care is taken during the driver removal in order to properly handle this state. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/core.c | 58 +++--- drivers/net/ethernet/mellanox/mlxsw/core.h | 4 +-- drivers/net/ethernet/mellanox/mlxsw/i2c.c | 4 +-- drivers/net/ethernet/mellanox/mlxsw/pci.c | 4 +-- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index ab93437..2fcde3c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -113,6 +113,7 @@ struct mlxsw_core { struct mlxsw_thermal *thermal; struct mlxsw_core_port *ports; unsigned int max_ports; + bool reload_fail; unsigned long driver_priv[0]; /* driver_priv has to be always the last item */ }; @@ -962,7 +963,24 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port, pool_type, p_cur, p_max); } +static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink) +{ + struct mlxsw_core *mlxsw_core = devlink_priv(devlink); + const struct mlxsw_bus *mlxsw_bus = mlxsw_core->bus; + int err; + + mlxsw_core_bus_device_unregister(mlxsw_core, true); + mlxsw_bus->reset(mlxsw_core->bus_priv); + err = mlxsw_core_bus_device_register(mlxsw_core->bus_info, +mlxsw_core->bus, +mlxsw_core->bus_priv, true); + if (err) + mlxsw_core->reload_fail = true; + return err; +} + static const struct devlink_ops mlxsw_devlink_ops = { + .reload = mlxsw_devlink_core_bus_device_reload, .port_type_set = mlxsw_devlink_port_type_set, .port_split = mlxsw_devlink_port_split, .port_unsplit = mlxsw_devlink_port_unsplit, @@ -980,7 +998,7 @@ static const struct devlink_ops mlxsw_devlink_ops = { int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, const struct mlxsw_bus *mlxsw_bus, - void *bus_priv) + void *bus_priv, bool reload) { const char *device_kind = mlxsw_bus_info->device_kind; struct mlxsw_core *mlxsw_core; @@ -992,11 +1010,14 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, mlxsw_driver = mlxsw_core_driver_get(device_kind); if (!mlxsw_driver) return -EINVAL; - alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size; - devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size); - if (!devlink) { - err = -ENOMEM; - goto err_devlink_alloc; + + if (!reload) { + alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size; + devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size); + if (!devlink) { + err = -ENOMEM; + goto err_devlink_alloc; + } } mlxsw_core = devlink_priv(devlink); @@ -1012,7 +1033,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, if (err) goto err_bus_init; - if (mlxsw_driver->resources_register) { + if (mlxsw_driver->resources_register && !reload) { err = mlxsw_driver->resources_register(mlxsw_core); if (err) goto err_register_resources; @@ -1038,9 +1059,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, if (err) goto err_emad_init; - err = devlink_register(devlink, mlxsw_bus_info->dev); - if (err) - goto err_devlink_register; + if (!reload) { + err = devlink_register(devlink, mlxsw_bus_info->dev); + if (err) + goto err_devlink_register; + } err = mlxsw_hwmon_init(mlxsw_core, mlxsw_bus_info, &mlxsw_core->hwmon); if (err) @@ -1082,20 +1105,29 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, } EXPORT_SYMBOL(mlxsw_core_bus_device_register); -void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core) +void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, + bool reload) {
[patch net-next RFC 6/7] mlxsw: pci: Add support for getting resource through devlink
From: Arkadi Sharshevsky Up until now the KVD partition was static. This patch introduces the ability to get the resource sizes via devlink. In case the resource is not available the default configuration is used. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/core.c | 16 drivers/net/ethernet/mellanox/mlxsw/core.h | 9 drivers/net/ethernet/mellanox/mlxsw/pci.c | 40 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 57 ++ 4 files changed, 92 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index ee41036..ab93437 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -1800,6 +1800,22 @@ void mlxsw_core_flush_owq(void) } EXPORT_SYMBOL(mlxsw_core_flush_owq); +int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core, +const struct mlxsw_config_profile *profile, +u64 *p_single_size, u64 *p_double_size, +u64 *p_linear_size) +{ + struct mlxsw_driver *driver = mlxsw_core->driver; + + if (!driver->kvd_sizes_get) + return -EINVAL; + + return driver->kvd_sizes_get(mlxsw_core, profile, +p_single_size, p_double_size, +p_linear_size); +} +EXPORT_SYMBOL(mlxsw_core_kvd_sizes_get); + static int __init mlxsw_core_module_init(void) { int err; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index e23f83b..e44061d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -309,10 +309,19 @@ struct mlxsw_driver { void (*txhdr_construct)(struct sk_buff *skb, const struct mlxsw_tx_info *tx_info); int (*resources_register)(struct mlxsw_core *mlxsw_core); + int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core, +const struct mlxsw_config_profile *profile, +u64 *p_single_size, u64 *p_double_size, +u64 *p_linear_size); u8 txhdr_len; const struct mlxsw_config_profile *profile; }; +int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core, +const struct mlxsw_config_profile *profile, +u64 *p_single_size, u64 *p_double_size, +u64 *p_linear_size); + bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core, enum mlxsw_res_id res_id); diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 00c9155..da08f08 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -1053,38 +1053,18 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox, } static int -mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_config_profile *profile, +mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_pci *mlxsw_pci, + const struct mlxsw_config_profile *profile, struct mlxsw_res *res) { - u32 single_size, double_size, linear_size; - - if (!MLXSW_RES_VALID(res, KVD_SINGLE_MIN_SIZE) || - !MLXSW_RES_VALID(res, KVD_DOUBLE_MIN_SIZE) || - !profile->used_kvd_split_data) - return -EIO; - - linear_size = profile->kvd_linear_size; + u64 single_size, double_size, linear_size; + int err; - /* The hash part is what left of the kvd without the -* linear part. It is split to the single size and -* double size by the parts ratio from the profile. -* Both sizes must be a multiplications of the -* granularity from the profile. -*/ - double_size = MLXSW_RES_GET(res, KVD_SIZE) - linear_size; - double_size *= profile->kvd_hash_double_parts; - double_size /= profile->kvd_hash_double_parts + - profile->kvd_hash_single_parts; - double_size /= profile->kvd_hash_granularity; - double_size *= profile->kvd_hash_granularity; - single_size = MLXSW_RES_GET(res, KVD_SIZE) - double_size - - linear_size; - - /* Check results are legal. */ - if (single_size < MLXSW_RES_GET(res, KVD_SINGLE_MIN_SIZE) || - double_size < MLXSW_RES_GET(res, KVD_DOUBLE_MIN_SIZE) || - MLXSW_RES_GET(res, KVD_SIZE) < linear_size) - return -EIO; + err = mlxsw_core_kvd_sizes_get(mlxsw_pci->core, profile, + &single_size, &double_size, + &linear_size); + if (err) + return err;
[patch net-next RFC 1/7] devlink: Add support for resource abstraction
From: Arkadi Sharshevsky Add support for hardware resource abstraction over devlink. Each resource is identified via unique name, furthermore it contains information regarding its size and its related sub resources. Each resource can also provide its current occupancy. In some cases the sizes of some resources can be changed, yet for those changes to take place a hot driver reload may be needed. The reload capability will be introduced in the next patch. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko --- include/net/devlink.h| 74 ++ include/uapi/linux/devlink.h | 8 ++ net/core/devlink.c | 317 +++ 3 files changed, 399 insertions(+) diff --git a/include/net/devlink.h b/include/net/devlink.h index b9654e1..fe57534 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -26,6 +26,7 @@ struct devlink { struct list_head port_list; struct list_head sb_list; struct list_head dpipe_table_list; + struct list_head resource_list; struct devlink_dpipe_headers *dpipe_headers; const struct devlink_ops *ops; struct device *dev; @@ -223,6 +224,43 @@ struct devlink_dpipe_headers { unsigned int headers_count; }; +/** + * struct devlink_resource_ops - resource ops + * @occ_get - get the occupied size + * @size_validate - validate the size of the resource before update, reload + * is needed for changes to take place + */ +struct devlink_resource_ops { + u64 (*occ_get)(void *priv); + int (*size_validate)(void *priv, u64 size); +}; + +/** + * struct devlink_resource - devlink resource + * @priv - private + * @name - name of the resource + * @size - size of the resource + * @size_new - updated size of the resource, reload is needed + * @id - id, per devlink instance + * @parent - parent resource + * @list - parent list + * @sub_resource_list - list of sub-resources + * @resource_ops - resource ops + */ +struct devlink_resource { + void *priv; + const char *name; + u64 size; + u64 size_new; + u64 id; + struct devlink_resource *parent; + struct list_head list; + struct list_head sub_resource_list; + struct devlink_resource_ops *resource_ops; +}; + +#define DEVLINK_RESOURCE_ID_PARENT_TOP 0 + struct devlink_ops { int (*port_type_set)(struct devlink_port *devlink_port, enum devlink_port_type port_type); @@ -331,6 +369,18 @@ int devlink_dpipe_match_put(struct sk_buff *skb, extern struct devlink_dpipe_header devlink_dpipe_header_ethernet; extern struct devlink_dpipe_header devlink_dpipe_header_ipv4; extern struct devlink_dpipe_header devlink_dpipe_header_ipv6; +int devlink_resource_register(struct devlink *devlink, + const char *resource_name, + bool top_hirarchy, + u64 resource_size, + u64 resource_id, + u64 parent_resource_id, + struct devlink_resource_ops *resource_ops, + void *priv); +int devlink_resource_size_get(struct devlink *devlink, + u64 resource_id, + u64 *p_resource_size); +void devlink_resources_clear(struct devlink *devlink); #else @@ -468,6 +518,30 @@ devlink_dpipe_match_put(struct sk_buff *skb, return 0; } +static inline int +devlink_resource_register(struct devlink *devlink, + const char *resource_name, + bool top_hirarchy, + u64 resource_size, + u64 resource_id, + u64 parent_resource_id, + struct devlink_resource_ops *resource_ops, + void *priv) +{ + return 0; +} + +static inline int +devlink_resource_size_get(struct devlink *devlink, u64 resource_id, + u64 *p_resource_size) +{ + return -EINVAL; +} + +static inline void devlink_resources_clear(struct devlink *devlink) +{ +} + #endif #endif /* _NET_DEVLINK_H_ */ diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 0cbca96..9db1d70 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -69,6 +69,8 @@ enum devlink_command { DEVLINK_CMD_DPIPE_ENTRIES_GET, DEVLINK_CMD_DPIPE_HEADERS_GET, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, + DEVLINK_CMD_RESOURCE_SET, + DEVLINK_CMD_RESOURCE_DUMP, /* add new commands above here */ __DEVLINK_CMD_MAX, @@ -201,6 +203,12 @@ enum devlink_attr { DEVLINK_ATTR_PAD, DEVLINK_ATTR_ESWITCH_ENCAP_MODE,/* u8 */ + DEVLINK_ATTR_RESOURCES, /* nested */ + DEVLINK_ATTR_RESOURCE, /* nested */ + DEVLINK_ATTR_RESOURCE_NAME,
Re: [PATCH v2] net: rxrpc: mark expected switch fall-throughs
From: "Gustavo A. R. Silva" Date: Thu, 19 Oct 2017 16:54:48 -0500 > In preparation to enabling -Wimplicit-fallthrough, mark switch cases > where we are expecting to fall through. > > Signed-off-by: Gustavo A. R. Silva > --- > This code was tested by compilation only (GCC 7.2.0 was used). > Please, verify if the actual intention of the code is to fall through. > > Changes in v2: > Start every "Fall through" comment with capital 'F'. > Put back blank lines. Applied.
[PATCH] drivers/wireless: cw1200: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Solomon Peachy Cc: Kalle Valo Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/st/cw1200/main.c | 3 +-- drivers/net/wireless/st/cw1200/queue.c | 6 +++--- drivers/net/wireless/st/cw1200/sta.c | 5 ++--- drivers/net/wireless/st/cw1200/sta.h | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/st/cw1200/main.c b/drivers/net/wireless/st/cw1200/main.c index dc478cedbde0..a186d1df1f29 100644 --- a/drivers/net/wireless/st/cw1200/main.c +++ b/drivers/net/wireless/st/cw1200/main.c @@ -373,8 +373,7 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr, INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work); INIT_WORK(&priv->set_beacon_wakeup_period_work, cw1200_set_beacon_wakeup_period_work); - setup_timer(&priv->mcast_timeout, cw1200_mcast_timeout, - (unsigned long)priv); + timer_setup(&priv->mcast_timeout, cw1200_mcast_timeout, 0); if (cw1200_queue_stats_init(&priv->tx_queue_stats, CW1200_LINK_ID_MAX, diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c index 0ba5ef9b3e7b..5153d2cfd991 100644 --- a/drivers/net/wireless/st/cw1200/queue.c +++ b/drivers/net/wireless/st/cw1200/queue.c @@ -130,11 +130,11 @@ static void __cw1200_queue_gc(struct cw1200_queue *queue, } } -static void cw1200_queue_gc(unsigned long arg) +static void cw1200_queue_gc(struct timer_list *t) { LIST_HEAD(list); struct cw1200_queue *queue = - (struct cw1200_queue *)arg; + from_timer(queue, t, gc); spin_lock_bh(&queue->lock); __cw1200_queue_gc(queue, &list, true); @@ -179,7 +179,7 @@ int cw1200_queue_init(struct cw1200_queue *queue, INIT_LIST_HEAD(&queue->pending); INIT_LIST_HEAD(&queue->free_pool); spin_lock_init(&queue->lock); - setup_timer(&queue->gc, cw1200_queue_gc, (unsigned long)queue); + timer_setup(&queue->gc, cw1200_queue_gc, 0); queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity, GFP_KERNEL); diff --git a/drivers/net/wireless/st/cw1200/sta.c b/drivers/net/wireless/st/cw1200/sta.c index a52224836a2b..03687a80d6e9 100644 --- a/drivers/net/wireless/st/cw1200/sta.c +++ b/drivers/net/wireless/st/cw1200/sta.c @@ -2112,10 +2112,9 @@ void cw1200_multicast_stop_work(struct work_struct *work) } } -void cw1200_mcast_timeout(unsigned long arg) +void cw1200_mcast_timeout(struct timer_list *t) { - struct cw1200_common *priv = - (struct cw1200_common *)arg; + struct cw1200_common *priv = from_timer(priv, t, mcast_timeout); wiphy_warn(priv->hw->wiphy, "Multicast delivery timeout.\n"); diff --git a/drivers/net/wireless/st/cw1200/sta.h b/drivers/net/wireless/st/cw1200/sta.h index a0bacaa39b31..719de34dcbfe 100644 --- a/drivers/net/wireless/st/cw1200/sta.h +++ b/drivers/net/wireless/st/cw1200/sta.h @@ -117,6 +117,6 @@ void cw1200_set_tim_work(struct work_struct *work); void cw1200_set_cts_work(struct work_struct *work); void cw1200_multicast_start_work(struct work_struct *work); void cw1200_multicast_stop_work(struct work_struct *work); -void cw1200_mcast_timeout(unsigned long arg); +void cw1200_mcast_timeout(struct timer_list *t); #endif -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] drivers/wireless: marvell/libertas: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: Arvind Yadav Cc: Ingo Molnar Cc: Johannes Berg Cc: "David S. Miller" Cc: Andrew Zaborowski Cc: libertas-...@lists.infradead.org Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/marvell/libertas/if_usb.c| 6 +++--- drivers/net/wireless/marvell/libertas/main.c | 21 + drivers/net/wireless/marvell/libertas_tf/if_usb.c | 6 +++--- drivers/net/wireless/marvell/libertas_tf/main.c | 7 +++ 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index 16e54c757dd0..ffea610f67e2 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -161,9 +161,9 @@ static void if_usb_setup_firmware(struct lbs_private *priv) } } -static void if_usb_fw_timeo(unsigned long priv) +static void if_usb_fw_timeo(struct timer_list *t) { - struct if_usb_card *cardp = (void *)priv; + struct if_usb_card *cardp = from_timer(cardp, t, fw_timeout); if (cardp->fwdnldover) { lbs_deb_usb("Download complete, no event. Assuming success\n"); @@ -205,7 +205,7 @@ static int if_usb_probe(struct usb_interface *intf, if (!cardp) goto error; - setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); + timer_setup(&cardp->fw_timeout, if_usb_fw_timeo, 0); init_waitqueue_head(&cardp->fw_wq); cardp->udev = udev; diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c index aefa88f4f29c..f22e1c220cba 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -722,9 +722,9 @@ EXPORT_SYMBOL_GPL(lbs_resume); * * @data: &struct lbs_private pointer */ -static void lbs_cmd_timeout_handler(unsigned long data) +static void lbs_cmd_timeout_handler(struct timer_list *t) { - struct lbs_private *priv = (struct lbs_private *)data; + struct lbs_private *priv = from_timer(priv, t, command_timer); unsigned long flags; spin_lock_irqsave(&priv->driver_lock, flags); @@ -756,9 +756,9 @@ static void lbs_cmd_timeout_handler(unsigned long data) * * @data: &struct lbs_private pointer */ -static void lbs_tx_lockup_handler(unsigned long data) +static void lbs_tx_lockup_handler(struct timer_list *t) { - struct lbs_private *priv = (struct lbs_private *)data; + struct lbs_private *priv = from_timer(priv, t, tx_lockup_timer); unsigned long flags; spin_lock_irqsave(&priv->driver_lock, flags); @@ -779,9 +779,9 @@ static void lbs_tx_lockup_handler(unsigned long data) * @data: &struct lbs_private pointer * returns:N/A */ -static void auto_deepsleep_timer_fn(unsigned long data) +static void auto_deepsleep_timer_fn(struct timer_list *t) { - struct lbs_private *priv = (struct lbs_private *)data; + struct lbs_private *priv = from_timer(priv, t, auto_deepsleep_timer); if (priv->is_activity_detected) { priv->is_activity_detected = 0; @@ -847,12 +847,9 @@ static int lbs_init_adapter(struct lbs_private *priv) init_waitqueue_head(&priv->fw_waitq); mutex_init(&priv->lock); - setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, - (unsigned long)priv); - setup_timer(&priv->tx_lockup_timer, lbs_tx_lockup_handler, - (unsigned long)priv); - setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, - (unsigned long)priv); + timer_setup(&priv->command_timer, lbs_cmd_timeout_handler, 0); + timer_setup(&priv->tx_lockup_timer, lbs_tx_lockup_handler, 0); + timer_setup(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, 0); INIT_LIST_HEAD(&priv->cmdfreeq); INIT_LIST_HEAD(&priv->cmdpendingq); diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c index e9104eca327b..5153922e7ce1 100644 --- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -115,9 +115,9 @@ static void if_usb_setup_firmware(struct lbtf_private *priv) lbtf_deb_leave(LBTF_DEB_USB); } -static void if_usb_fw_timeo(unsigned long priv) +static void if_usb_fw_timeo(struct timer_list *t) { - struct if_usb_card *cardp = (void *)priv; + struct if_usb_card *cardp = from_timer(cardp, t, fw_timeout); lbtf_deb_enter(LBTF_DEB_USB); if (!cardp->fwdnldover) { @@ -156,7 +156,7 @@ static int if_usb_probe(struct usb_interface *intf, if (!cardp)
[PATCH] drivers/wireless: marvell/mwifiex: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: Amitkumar Karwar Cc: Nishant Sarmukadam Cc: Ganapathi Bhat Cc: Xinming Hu Cc: Arvind Yadav Cc: Ingo Molnar Cc: Johannes Berg Cc: "David S. Miller" Cc: Andrew Zaborowski Cc: libertas-...@lists.infradead.org Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c | 7 +++ drivers/net/wireless/marvell/mwifiex/cmdevt.c| 5 ++--- drivers/net/wireless/marvell/mwifiex/init.c | 7 +++ drivers/net/wireless/marvell/mwifiex/main.c | 3 +-- drivers/net/wireless/marvell/mwifiex/main.h | 4 ++-- drivers/net/wireless/marvell/mwifiex/tdls.c | 7 +++ drivers/net/wireless/marvell/mwifiex/usb.c | 9 - 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c index 274dd5a1574a..fd58157d69fb 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c @@ -312,10 +312,10 @@ mwifiex_11n_find_last_seq_num(struct reorder_tmr_cnxt *ctx) * them and then dumps the Rx reordering table. */ static void -mwifiex_flush_data(unsigned long context) +mwifiex_flush_data(struct timer_list *t) { struct reorder_tmr_cnxt *ctx = - (struct reorder_tmr_cnxt *) context; + from_timer(ctx, t, timer); int start_win, seq_num; ctx->timer_is_set = false; @@ -412,8 +412,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, new_node->timer_context.priv = priv; new_node->timer_context.timer_is_set = false; - setup_timer(&new_node->timer_context.timer, mwifiex_flush_data, - (unsigned long)&new_node->timer_context); + timer_setup(&new_node->timer_context.timer, mwifiex_flush_data, 0); for (i = 0; i < win_size; ++i) new_node->rx_reorder_ptr[i] = NULL; diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c index 0edc5d621304..57c6a880e757 100644 --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -922,10 +922,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) * It will re-send the same command again. */ void -mwifiex_cmd_timeout_func(unsigned long function_context) +mwifiex_cmd_timeout_func(struct timer_list *t) { - struct mwifiex_adapter *adapter = - (struct mwifiex_adapter *) function_context; + struct mwifiex_adapter *adapter = from_timer(adapter, t, cmd_timer); struct cmd_ctrl_node *cmd_node; adapter->is_cmd_timedout = 1; diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c index e11919db7818..9005c4129a51 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -52,9 +52,9 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) return 0; } -static void wakeup_timer_fn(unsigned long data) +static void wakeup_timer_fn(struct timer_list *t) { - struct mwifiex_adapter *adapter = (struct mwifiex_adapter *)data; + struct mwifiex_adapter *adapter = from_timer(adapter, t, wakeup_timer); mwifiex_dbg(adapter, ERROR, "Firmware wakeup failed\n"); adapter->hw_status = MWIFIEX_HW_STATUS_RESET; @@ -313,8 +313,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM; adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM; adapter->active_scan_triggered = false; - setup_timer(&adapter->wakeup_timer, wakeup_timer_fn, - (unsigned long)adapter); + timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0); } /* diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index ee40b739b289..a96bd7e653bf 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -100,8 +100,7 @@ static int mwifiex_register(void *card, struct device *dev, } mwifiex_init_lock_list(adapter); - setup_timer(&adapter->cmd_timer, mwifiex_cmd_timeout_func, - (unsigned long)adapter); + timer_setup(&adapter->cmd_timer, mwifiex_cmd_timeout_func, 0); return 0; diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index a34de8582e91..154c0796c0c5 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@
[PATCH] drivers/wireless: iwlwifi/mvm: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. The RCU lifetime on baid_data is unclear, so this adds a direct copy of the rcu_ptr passed to the original callback. It may be possible to improve this to just use baid_data->mvm->baid_map[baid_data->baid] instead. Cc: Johannes Berg Cc: Emmanuel Grumbach Cc: Luca Coelho Cc: Intel Linux Wireless Cc: Kalle Valo Cc: Sara Sharon Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 ++- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 18 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index bf25c3ce7c95..a22c0ecff324 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -636,6 +636,7 @@ struct iwl_mvm_baid_data { u16 timeout; unsigned long last_rx; struct timer_list session_timer; + struct iwl_mvm_baid_data __rcu **rcu_ptr; struct iwl_mvm *mvm; struct iwl_mvm_reorder_buffer reorder_buf[]; }; @@ -1829,7 +1830,7 @@ void iwl_mvm_tdls_ch_switch_work(struct work_struct *work); void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, struct iwl_mvm_internal_rxq_notif *notif, u32 size); -void iwl_mvm_reorder_timer_expired(unsigned long data); +void iwl_mvm_reorder_timer_expired(struct timer_list *t); struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 5e679859f948..53485dc096b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -456,9 +456,9 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm, } } -void iwl_mvm_reorder_timer_expired(unsigned long data) +void iwl_mvm_reorder_timer_expired(struct timer_list *t) { - struct iwl_mvm_reorder_buffer *buf = (void *)data; + struct iwl_mvm_reorder_buffer *buf = from_timer(buf, t, reorder_timer); int i; u16 sn = 0, index = 0; bool expired = false; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 282424f40c43..b95b24a03959 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -252,9 +252,11 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, return ret; } -static void iwl_mvm_rx_agg_session_expired(unsigned long data) +static void iwl_mvm_rx_agg_session_expired(struct timer_list *t) { - struct iwl_mvm_baid_data __rcu **rcu_ptr = (void *)data; + struct iwl_mvm_baid_data *data = + from_timer(data, t, session_timer); + struct iwl_mvm_baid_data __rcu **rcu_ptr = data->rcu_ptr; struct iwl_mvm_baid_data *ba_data; struct ieee80211_sta *sta; struct iwl_mvm_sta *mvm_sta; @@ -2150,10 +2152,8 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm, reorder_buf->head_sn = ssn; reorder_buf->buf_size = buf_size; /* rx reorder timer */ - reorder_buf->reorder_timer.function = - iwl_mvm_reorder_timer_expired; - reorder_buf->reorder_timer.data = (unsigned long)reorder_buf; - init_timer(&reorder_buf->reorder_timer); + timer_setup(&reorder_buf->reorder_timer, + iwl_mvm_reorder_timer_expired, 0); spin_lock_init(&reorder_buf->lock); reorder_buf->mvm = mvm; reorder_buf->queue = i; @@ -2250,9 +2250,9 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, baid_data->baid = baid; baid_data->timeout = timeout; baid_data->last_rx = jiffies; - setup_timer(&baid_data->session_timer, - iwl_mvm_rx_agg_session_expired, - (unsigned long)&mvm->baid_map[baid]); + baid_data->rcu_ptr = &mvm->baid_map[baid]; + timer_setup(&baid_data->session_timer, + iwl_mvm_rx_agg_session_expired, 0); baid_data->mvm = mvm; baid_data->tid = tid; baid_data->sta_id = mvm_sta->sta_id; -- 2.7.4 -- Kees Cook Pixel Security
Re: [PATCH v2] net: smc_close: mark expected switch fall-through
From: "Gustavo A. R. Silva" Date: Sat, 21 Oct 2017 20:35:30 -0500 > In preparation to enabling -Wimplicit-fallthrough, mark switch cases > where we are expecting to fall through. > > Notice that in this particular case I placed the "fall through" comment > on its own line, which is what GCC is expecting to find. > > Signed-off-by: Gustavo A. R. Silva > --- > Changes in v2: > Move the "fall through" comment on its own line > above the rest of the sentence. Applied.
Re: [PATCH] drivers/net/usb: add device id for TP-LINK UE300 USB 3.0 Ethernet
From: Ran Wang Date: Mon, 23 Oct 2017 18:10:23 +0800 > This product is named 'TP-LINK USB 3.0 Gigabit Ethernet Network > Adapter (Model No.is UE300)'. It uses chip RTL8153 and works with > driver drivers/net/usb/r8152.c > > Signed-off-by: Ran Wang Applied.
RE: [PATCH] ipv4: esp4: use BUG_ON instead of if condition followed by BUG
> Subject: [PATCH] ipv4: esp4: use BUG_ON instead of if condition followed by > BUG > > Use BUG_ON instead of if condition followed by BUG in esp_remove_trailer. > > This issue was detected with the help of Coccinelle. > > Signed-off-by: Gustavo A. R. Silva > --- > net/ipv4/esp4.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > Please consider esp6 as well.
[PATCH] drivers/wireless: ath: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/ath/ar5523/ar5523.c | 7 +++ drivers/net/wireless/ath/ath10k/htt_rx.c | 6 +++--- drivers/net/wireless/ath/ath10k/pci.c | 17 - drivers/net/wireless/ath/ath10k/pci.h | 2 +- drivers/net/wireless/ath/ath6kl/cfg80211.c| 6 ++ drivers/net/wireless/ath/ath6kl/core.h| 2 +- drivers/net/wireless/ath/ath6kl/main.c| 5 ++--- drivers/net/wireless/ath/ath6kl/txrx.c| 6 +++--- drivers/net/wireless/ath/ath6kl/wmi.c | 4 ++-- drivers/net/wireless/ath/ath6kl/wmi.h | 2 +- drivers/net/wireless/ath/ath9k/ath9k.h| 4 ++-- drivers/net/wireless/ath/ath9k/channel.c | 14 ++ drivers/net/wireless/ath/ath9k/gpio.c | 14 ++ drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 4 ++-- drivers/net/wireless/ath/ath9k/init.c | 4 ++-- drivers/net/wireless/ath/ath9k/link.c | 6 +++--- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- drivers/net/wireless/ath/wil6210/main.c | 15 +++ drivers/net/wireless/ath/wil6210/p2p.c| 4 ++-- drivers/net/wireless/ath/wil6210/wil6210.h| 2 +- 22 files changed, 61 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 68f0463ed8df..b94759daeacc 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -889,9 +889,9 @@ static void ar5523_tx_work(struct work_struct *work) mutex_unlock(&ar->mutex); } -static void ar5523_tx_wd_timer(unsigned long arg) +static void ar5523_tx_wd_timer(struct timer_list *t) { - struct ar5523 *ar = (struct ar5523 *) arg; + struct ar5523 *ar = from_timer(ar, t, tx_wd_timer); ar5523_dbg(ar, "TX watchdog timer triggered\n"); ieee80211_queue_work(ar->hw, &ar->tx_wd_work); @@ -1599,8 +1599,7 @@ static int ar5523_probe(struct usb_interface *intf, mutex_init(&ar->mutex); INIT_DELAYED_WORK(&ar->stat_work, ar5523_stat_work); - init_timer(&ar->tx_wd_timer); - setup_timer(&ar->tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar); + timer_setup(&ar->tx_wd_timer, ar5523_tx_wd_timer, 0); INIT_WORK(&ar->tx_wd_work, ar5523_tx_wd_work); INIT_WORK(&ar->tx_work, ar5523_tx_work); INIT_LIST_HEAD(&ar->tx_queue_pending); diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index a3f5dc78353f..f068376ec565 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -200,9 +200,9 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt) spin_unlock_bh(&htt->rx_ring.lock); } -static void ath10k_htt_rx_ring_refill_retry(unsigned long arg) +static void ath10k_htt_rx_ring_refill_retry(struct timer_list *t) { - struct ath10k_htt *htt = (struct ath10k_htt *)arg; + struct ath10k_htt *htt = from_timer(htt, t, rx_ring.refill_retry_timer); ath10k_htt_rx_msdu_buff_replenish(htt); } @@ -507,7 +507,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) *htt->rx_ring.alloc_idx.vaddr = 0; /* Initialize the Rx refill retry timer */ - setup_timer(timer, ath10k_htt_rx_ring_refill_retry, (unsigned long)htt); + timer_setup(timer, ath10k_htt_rx_ring_refill_retry, 0); spin_lock_init(&htt->rx_ring.lock); diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 195dafb98131..2b975bb3f67e 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -585,10 +585,10 @@ static void ath10k_pci_sleep(struct ath10k *ar) spin_unlock_irqrestore(&ar_pci->ps_lock, flags); } -static void ath10k_pci_ps_timer(unsigned long ptr) +static void ath10k_pci_ps_timer(struct timer_list *t) { - struct ath10k *ar = (void *)ptr; - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + struct ath10k_pci *ar_pci = from_timer(ar_pci, t, ps_timer); + struct ath10k *ar = ar_pci->ar; unsigned long flags; spin_lock_irqsave(&ar_pci->ps_lock, flags); @@ -838,9 +838,10 @@ void ath10k_pci_rx_post(struct ath10k *ar) ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]); } -void ath10k_pci_rx_replenish_retry(unsigned long ptr) +void ath10k_pci_rx_replenish_retry(struct timer_list *t) { - struct ath10k *ar = (void *)ptr; + struct ath10k_pci *ar_pci = from_timer(ar_pci, t, rx_post_retry);
[PATCH] drivers/wireless: rsi: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: Amitkumar Karwar Cc: Prameela Rani Garnepudi Cc: Pavani Muthyala Cc: Karun Eagalapati Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/rsi/rsi_91x_hal.c | 7 +++ drivers/net/wireless/rsi/rsi_91x_mac80211.c | 4 ++-- drivers/net/wireless/rsi/rsi_91x_main.c | 4 +--- drivers/net/wireless/rsi/rsi_common.h | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index 689527d7007a..1176de646942 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -418,9 +418,9 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb) return 0; } -static void bl_cmd_timeout(unsigned long priv) +static void bl_cmd_timeout(struct timer_list *t) { - struct rsi_hw *adapter = (struct rsi_hw *)priv; + struct rsi_hw *adapter = from_timer(adapter, t, bl_cmd_timer); adapter->blcmd_timer_expired = true; del_timer(&adapter->bl_cmd_timer); @@ -428,8 +428,7 @@ static void bl_cmd_timeout(unsigned long priv) static int bl_start_cmd_timer(struct rsi_hw *adapter, u32 timeout) { - setup_timer(&adapter->bl_cmd_timer, (void *)&bl_cmd_timeout, - (unsigned long)adapter); + timer_setup(&adapter->bl_cmd_timer, bl_cmd_timeout, 0); adapter->bl_cmd_timer.expires = (msecs_to_jiffies(timeout) + jiffies); adapter->blcmd_timer_expired = false; diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index b1f5dbbde3cb..9427c9d7c9c7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -1663,9 +1663,9 @@ static void rsi_resume_conn_channel(struct rsi_common *common) } } -void rsi_roc_timeout(unsigned long data) +void rsi_roc_timeout(struct timer_list *t) { - struct rsi_common *common = (struct rsi_common *)data; + struct rsi_common *common = from_timer(common, t, roc_timer); rsi_dbg(INFO_ZONE, "Remain on channel expired\n"); diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c index 71b8cfb8252e..2a1fbb7db6c4 100644 --- a/drivers/net/wireless/rsi/rsi_91x_main.c +++ b/drivers/net/wireless/rsi/rsi_91x_main.c @@ -262,9 +262,7 @@ struct rsi_hw *rsi_91x_init(void) rsi_default_ps_params(adapter); spin_lock_init(&adapter->ps_lock); - common->roc_timer.data = (unsigned long)common; - common->roc_timer.function = (void *)&rsi_roc_timeout; - init_timer(&common->roc_timer); + timer_setup(&common->roc_timer, rsi_roc_timeout, 0); common->init_done = true; return adapter; diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h index 272e18d750ff..29acaea3636d 100644 --- a/drivers/net/wireless/rsi/rsi_common.h +++ b/drivers/net/wireless/rsi/rsi_common.h @@ -85,5 +85,5 @@ void rsi_91x_deinit(struct rsi_hw *adapter); int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len); struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr); struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac); -void rsi_roc_timeout(unsigned long data); +void rsi_roc_timeout(struct timer_list *t); #endif -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] drivers/wireless: atmel: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Simon Kelley Cc: Kalle Valo Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/atmel/atmel.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/atmel/atmel.c b/drivers/net/wireless/atmel/atmel.c index e816d53c2c05..c9dd5e44c9c6 100644 --- a/drivers/net/wireless/atmel/atmel.c +++ b/drivers/net/wireless/atmel/atmel.c @@ -586,7 +586,7 @@ static int atmel_validate_channel(struct atmel_private *priv, int channel); static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, u16 frame_len, u8 rssi); -static void atmel_management_timer(u_long a); +static void atmel_management_timer(struct timer_list *t); static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size); static int atmel_send_command_wait(struct atmel_private *priv, int command, @@ -1579,8 +1579,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, priv->default_beacon_period = priv->beacon_period = 100; priv->listen_interval = 1; - setup_timer(&priv->management_timer, atmel_management_timer, - (unsigned long)dev); + timer_setup(&priv->management_timer, atmel_management_timer, 0); spin_lock_init(&priv->irqlock); spin_lock_init(&priv->timerlock); @@ -3434,10 +3433,9 @@ static void atmel_management_frame(struct atmel_private *priv, } /* run when timer expires */ -static void atmel_management_timer(u_long a) +static void atmel_management_timer(struct timer_list *t) { - struct net_device *dev = (struct net_device *) a; - struct atmel_private *priv = netdev_priv(dev); + struct atmel_private *priv = from_timer(priv, t, management_timer); unsigned long flags; /* Check if the card has been yanked. */ -- 2.7.4 -- Kees Cook Pixel Security
[PATCH] drivers/wireless: iwlegacy: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: Stanislaw Gruszka Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/intel/iwlegacy/3945-mac.c | 2 +- drivers/net/wireless/intel/iwlegacy/3945-rs.c | 10 +++--- drivers/net/wireless/intel/iwlegacy/4965-mac.c | 9 - drivers/net/wireless/intel/iwlegacy/common.c | 4 ++-- drivers/net/wireless/intel/iwlegacy/common.h | 2 +- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c index 329f3a63dadd..4b53ebf00c7f 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c @@ -3429,7 +3429,7 @@ il3945_setup_deferred_work(struct il_priv *il) il3945_hw_setup_deferred_work(il); - setup_timer(&il->watchdog, il_bg_watchdog, (unsigned long)il); + timer_setup(&il->watchdog, il_bg_watchdog, 0); tasklet_init(&il->irq_tasklet, (void (*)(unsigned long))il3945_irq_tasklet, diff --git a/drivers/net/wireless/intel/iwlegacy/3945-rs.c b/drivers/net/wireless/intel/iwlegacy/3945-rs.c index b2f35dfbc01b..e8983c6a2b7b 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-rs.c @@ -181,9 +181,9 @@ il3945_rate_scale_flush_wins(struct il3945_rs_sta *rs_sta) #define IL_AVERAGE_PACKETS 1500 static void -il3945_bg_rate_scale_flush(unsigned long data) +il3945_bg_rate_scale_flush(struct timer_list *t) { - struct il3945_rs_sta *rs_sta = (void *)data; + struct il3945_rs_sta *rs_sta = from_timer(rs_sta, t, rate_scale_flush); struct il_priv *il __maybe_unused = rs_sta->il; int unflushed = 0; unsigned long flags; @@ -360,9 +360,6 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) rs_sta->flush_time = RATE_FLUSH; rs_sta->last_tx_packets = 0; - rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; - rs_sta->rate_scale_flush.function = il3945_bg_rate_scale_flush; - for (i = 0; i < RATE_COUNT_3945; i++) il3945_clear_win(&rs_sta->win[i]); @@ -415,8 +412,7 @@ il3945_rs_alloc_sta(void *il_priv, struct ieee80211_sta *sta, gfp_t gfp) rs_sta = &psta->rs_sta; spin_lock_init(&rs_sta->lock); - init_timer(&rs_sta->rate_scale_flush); - + timer_setup(&rs_sta->rate_scale_flush, il3945_bg_rate_scale_flush, 0); D_RATE("leave\n"); return rs_sta; diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index 65eba2c24292..de63f2518f23 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -4074,9 +4074,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb) * used for calibrating the TXPOWER. */ static void -il4965_bg_stats_periodic(unsigned long data) +il4965_bg_stats_periodic(struct timer_list *t) { - struct il_priv *il = (struct il_priv *)data; + struct il_priv *il = from_timer(il, t, stats_periodic); if (test_bit(S_EXIT_PENDING, &il->status)) return; @@ -6258,10 +6258,9 @@ il4965_setup_deferred_work(struct il_priv *il) INIT_WORK(&il->txpower_work, il4965_bg_txpower_work); - setup_timer(&il->stats_periodic, il4965_bg_stats_periodic, - (unsigned long)il); + timer_setup(&il->stats_periodic, il4965_bg_stats_periodic, 0); - setup_timer(&il->watchdog, il_bg_watchdog, (unsigned long)il); + timer_setup(&il->watchdog, il_bg_watchdog, 0); tasklet_init(&il->irq_tasklet, (void (*)(unsigned long))il4965_irq_tasklet, diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 8d5acda92a9b..558bb16bfd46 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -4844,9 +4844,9 @@ il_check_stuck_queue(struct il_priv *il, int cnt) * we reset the firmware. If everything is fine just rearm the timer. */ void -il_bg_watchdog(unsigned long data) +il_bg_watchdog(struct timer_list *t) { - struct il_priv *il = (struct il_priv *)data; + struct il_priv *il = from_timer(il, t, watchdog); int cnt; unsigned long timeout; diff --git a/drivers/net/wireless/intel/iwlegacy/common.h b/drivers/net/wireless/intel/iwlegacy/common.h index 18c60c92e3a3..dc6a74a05983 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.h +++ b/drivers/net/wireless/intel/iwlegacy/common.h @@ -1832,7 +1832,7 @@ int il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd); * PCI
[PATCH] drivers/wireless: qtnfmac: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: Igor Mitsyanko Cc: Avinash Patil Cc: Sergey Matyukevich Cc: Kamlesh Rath Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 7 +++ drivers/net/wireless/quantenna/qtnfmac/core.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index 32bf72c0399f..ac1b9bd5ed90 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -581,9 +581,9 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev, return ret; } -static void qtnf_scan_timeout(unsigned long data) +static void qtnf_scan_timeout(struct timer_list *t) { - struct qtnf_wmac *mac = (struct qtnf_wmac *)data; + struct qtnf_wmac *mac = from_timer(mac, t, scan_timeout); pr_warn("mac%d scan timed out\n", mac->macid); qtnf_scan_done(mac, true); @@ -602,8 +602,7 @@ qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) return -EFAULT; } - mac->scan_timeout.data = (unsigned long)mac; - mac->scan_timeout.function = qtnf_scan_timeout; + mac->scan_timeout.function = (TIMER_FUNC_TYPE)qtnf_scan_timeout; mod_timer(&mac->scan_timeout, jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ); diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c index 5e60180482d1..aa7f146278a7 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@ -289,7 +289,7 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus, mac->iflist[i].vifid = i; qtnf_sta_list_init(&mac->iflist[i].sta_list); mutex_init(&mac->mac_lock); - init_timer(&mac->scan_timeout); + setup_timer(&mac->scan_timeout, NULL, 0); } qtnf_mac_init_primary_intf(mac); -- 2.7.4 -- Kees Cook Pixel Security
Re: [PATCH net 3/3] net: mvpp2: do not call txq_done from the Tx path when Tx irqs are used
From: Antoine Tenart Date: Mon, 23 Oct 2017 15:24:31 +0200 > When Tx IRQs are used, txq_bufs_free() can be called from both the Tx > path and from NAPI poll(). This led to CPU stalls as if these two tasks > (Tx and Poll) are scheduled on two CPUs at the same time, DMA unmapping > operations are done on the same txq buffers. > > This patch adds a check not to call txq_done() from the Tx path if Tx > interrupts are used as it does not make sense to do so. > > Fixes: edc660fa09e2 ("net: mvpp2: replace TX coalescing interrupts with > hrtimer") > Signed-off-by: Antoine Tenart Applied.
[PATCH net-next 1/2] net: dsa: lan9303: Move struct lan9303 to include/linux/lan9303.h
The next patch require net/dsa/tag_lan9303.c to access struct lan9303. Therefore move struct lan9303 definitions from drivers/net/dsa/lan9303.h to new file include/linux/lan9303.h. Signed-off-by: Egil Hjelmeland --- MAINTAINERS | 1 + drivers/net/dsa/lan9303.h | 34 +- include/linux/lan9303.h | 35 +++ 3 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 include/linux/lan9303.h diff --git a/MAINTAINERS b/MAINTAINERS index e3a7ca9d2783..9535e32bd421 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9416,6 +9416,7 @@ S:Maintained F: net/dsa/ F: include/net/dsa.h F: drivers/net/dsa/ +F: include/linux/lan9303.h NETWORKING [GENERAL] M: "David S. Miller" diff --git a/drivers/net/dsa/lan9303.h b/drivers/net/dsa/lan9303.h index d807b1be35f2..e6675e11c833 100644 --- a/drivers/net/dsa/lan9303.h +++ b/drivers/net/dsa/lan9303.h @@ -2,39 +2,7 @@ #include #include -struct lan9303; - -struct lan9303_phy_ops { - /* PHY 1 and 2 access*/ - int (*phy_read)(struct lan9303 *chip, int port, int regnum); - int (*phy_write)(struct lan9303 *chip, int port, -int regnum, u16 val); -}; - -#define LAN9303_NUM_ALR_RECORDS 512 -struct lan9303_alr_cache_entry { - u8 mac_addr[ETH_ALEN]; - u8 port_map; /* Bitmap of ports. Zero if unused entry */ - u8 stp_override; /* non zero if set ALR_DAT1_AGE_OVERRID */ -}; - -struct lan9303 { - struct device *dev; - struct regmap *regmap; - struct regmap_irq_chip_data *irq_data; - struct gpio_desc *reset_gpio; - u32 reset_duration; /* in [ms] */ - bool phy_addr_sel_strap; - struct dsa_switch *ds; - struct mutex indirect_mutex; /* protect indexed register access */ - const struct lan9303_phy_ops *ops; - bool is_bridged; /* true if port 1 and 2 are bridged */ - u32 swe_port_state; /* remember SWE_PORT_STATE while not bridged */ - /* LAN9303 do not offer reading specific ALR entry. Cache all -* static entries in a flat table -**/ - struct lan9303_alr_cache_entry alr_cache[LAN9303_NUM_ALR_RECORDS]; -}; +#include extern const struct regmap_access_table lan9303_register_set; extern const struct lan9303_phy_ops lan9303_indirect_phy_ops; diff --git a/include/linux/lan9303.h b/include/linux/lan9303.h new file mode 100644 index ..5810bdb43581 --- /dev/null +++ b/include/linux/lan9303.h @@ -0,0 +1,35 @@ +/* Included by drivers/net/dsa/lan9303.h and net/dsa/tag_lan9303.c */ + +struct lan9303; + +struct lan9303_phy_ops { + /* PHY 1 and 2 access*/ + int (*phy_read)(struct lan9303 *chip, int port, int regnum); + int (*phy_write)(struct lan9303 *chip, int port, +int regnum, u16 val); +}; + +#define LAN9303_NUM_ALR_RECORDS 512 +struct lan9303_alr_cache_entry { + u8 mac_addr[ETH_ALEN]; + u8 port_map; /* Bitmap of ports. Zero if unused entry */ + u8 stp_override; /* non zero if set ALR_DAT1_AGE_OVERRID */ +}; + +struct lan9303 { + struct device *dev; + struct regmap *regmap; + struct regmap_irq_chip_data *irq_data; + struct gpio_desc *reset_gpio; + u32 reset_duration; /* in [ms] */ + bool phy_addr_sel_strap; + struct dsa_switch *ds; + struct mutex indirect_mutex; /* protect indexed register access */ + const struct lan9303_phy_ops *ops; + bool is_bridged; /* true if port 1 and 2 are bridged */ + u32 swe_port_state; /* remember SWE_PORT_STATE while not bridged */ + /* LAN9303 do not offer reading specific ALR entry. Cache all +* static entries in a flat table +**/ + struct lan9303_alr_cache_entry alr_cache[LAN9303_NUM_ALR_RECORDS]; +}; -- 2.11.0
[PATCH net-next 2/2] net: dsa: lan9303: Learn addresses on CPU port when bridged
When CPU transmit directly to port using tag, the LAN9303 does not learn MAC addresses received on the CPU port into the ALR. ALR learning is performed only when transmitting using ALR lookup. Solution: If the two external ports are bridged and the packet is not STP BPDU, then use ALR lookup to allow ALR learning on CPU port. Otherwise transmit directly to port with STP state override. Signed-off-by: Egil Hjelmeland --- net/dsa/tag_lan9303.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index 57519597c6fc..174721293a34 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -12,6 +12,7 @@ * */ #include +#include #include #include @@ -39,6 +40,23 @@ */ #define LAN9303_TAG_LEN 4 +# define LAN9303_TAG_TX_USE_ALR BIT(3) +# define LAN9303_TAG_TX_STP_OVERRIDE BIT(4) +#define eth_stp_addr eth_reserved_addr_base + +/* Decide whether to transmit using ALR lookup, or transmit directly to + * port using tag. ALR learning is performed only when using ALR lookup. + * If the two external ports are bridged and the packet is not STP BPDU, + * then use ALR lookup to allow ALR learning on CPU port. + * Otherwise transmit directly to port with STP state override. + * See also: lan9303_separate_ports() and lan9303.pdf 6.4.10.1 + */ +static inline int lan9303_tx_use_arl(struct dsa_port *dp, u8 *dest_addr) +{ + struct lan9303 *chip = dp->ds->priv; + + return chip->is_bridged && !ether_addr_equal(dest_addr, eth_stp_addr); +} static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -62,7 +80,10 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) lan9303_tag = (u16 *)(skb->data + 2 * ETH_ALEN); lan9303_tag[0] = htons(ETH_P_8021Q); - lan9303_tag[1] = htons(dp->index | BIT(4)); + lan9303_tag[1] = lan9303_tx_use_arl(dp, skb->data) ? + LAN9303_TAG_TX_USE_ALR : + dp->index | LAN9303_TAG_TX_STP_OVERRIDE; + lan9303_tag[1] = htons(lan9303_tag[1]); return skb; } -- 2.11.0
[PATCH net-next 0/2] net: dsa: lan9303: Learn addresses on CPU port when bridged
When CPU transmit directly to port using tag, the LAN9303 does not learn MAC addresses received on the CPU port into the ALR table. ALR learning is performed only when transmitting using ALR lookup. Solution: If the two external ports are bridged and the packet is not STP BPDU, then use ALR lookup to allow ALR learning on CPU port. Otherwise transmit directly to port with STP state override. The first patch moves struct lan9303 to include/linux/lan9303.h in order to prepare for the second patch. Egil Hjelmeland (2): net: dsa: lan9303: Move struct lan9303 to include/linux/lan9303.h net: dsa: lan9303: Learn addresses on CPU port when bridged MAINTAINERS | 1 + drivers/net/dsa/lan9303.h | 34 +- include/linux/lan9303.h | 35 +++ net/dsa/tag_lan9303.c | 23 ++- 4 files changed, 59 insertions(+), 34 deletions(-) create mode 100644 include/linux/lan9303.h -- 2.11.0
Re: [PATCH] cdc_ether: flag the Huawei ME906/ME909 as WWAN
From: Aleksander Morgado Date: Mon, 23 Oct 2017 17:16:41 +0200 > The Huawei ME906 (12d1:15c1) comes with a standard ECM interface that > requires management via AT commands sent over one of the control TTYs > (e.g. connected with AT^NDISDUP). > > Signed-off-by: Aleksander Morgado Applied.
Re: [PATCH net 2/3] net: mvpp2: do not unmap TSO headers buffers
From: Antoine Tenart Date: Mon, 23 Oct 2017 15:24:30 +0200 > The TSO header buffers are coming from a per cpu pool and should not > be unmapped as they are reused. The PPv2 driver was unmapping all > descriptors buffers unconditionally. This patch fixes this by checking > the buffers dma addresses before unmapping them, and by not unmapping > those who are located in the TSO header pool. > > Fixes: 186cd4d4e414 ("net: mvpp2: software tso support") > Signed-off-by: Antoine Tenart Applied.
Re: [PATCH net 1/3] net: mvpp2: fix TSO headers allocation and management
From: Antoine Tenart Date: Mon, 23 Oct 2017 15:24:29 +0200 > From: Yan Markman > > TSO headers are managed with txq index and therefore should be aligned > with the txq size, not with the aggregated txq size. > > Fixes: 186cd4d4e414 ("net: mvpp2: software tso support") > Reported-by: Marc Zyngier > Signed-off-by: Yan Markman > Signed-off-by: Antoine Tenart Applied.
[PATCH] drivers/wireless: rtlwifi: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Kalle Valo Cc: Larry Finger Cc: Chaoming Li Cc: Ping-Ke Shih Cc: Arvind Yadav Cc: Souptick Joarder Cc: linux-wirel...@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook --- drivers/net/wireless/realtek/rtlwifi/base.c | 20 ++-- drivers/net/wireless/realtek/rtlwifi/base.h | 4 ++-- drivers/net/wireless/realtek/rtlwifi/core.c | 2 +- drivers/net/wireless/realtek/rtlwifi/ps.c | 2 +- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c | 6 -- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h | 2 +- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 7 +-- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h | 2 +- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 12 9 files changed, 29 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index ea18aa7afecb..03482deb1558 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -461,10 +461,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); /* <1> timer */ - setup_timer(&rtlpriv->works.watchdog_timer, - rtl_watch_dog_timer_callback, (unsigned long)hw); - setup_timer(&rtlpriv->works.dualmac_easyconcurrent_retrytimer, - rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw); + timer_setup(&rtlpriv->works.watchdog_timer, + rtl_watch_dog_timer_callback, 0); + timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer, + rtl_easy_concurrent_retrytimer_callback, 0); /* <2> work queue */ rtlpriv->works.hw = hw; rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); @@ -1975,10 +1975,9 @@ void rtl_watchdog_wq_callback(void *data) rtl_scan_list_expire(hw); } -void rtl_watch_dog_timer_callback(unsigned long data) +void rtl_watch_dog_timer_callback(struct timer_list *t) { - struct ieee80211_hw *hw = (struct ieee80211_hw *)data; - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv = from_timer(rtlpriv, t, works.watchdog_timer); queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.watchdog_wq, 0); @@ -2084,10 +2083,11 @@ void rtl_c2hcmd_wq_callback(void *data) rtl_c2hcmd_launcher(hw, 1); } -void rtl_easy_concurrent_retrytimer_callback(unsigned long data) +void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t) { - struct ieee80211_hw *hw = (struct ieee80211_hw *)data; - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv = + from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer); + struct ieee80211_hw *hw = rtlpriv->hw; struct rtl_priv *buddy_priv = rtlpriv->buddy_priv; if (buddy_priv == NULL) diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h index b56d1b7f5567..23f1564811b8 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.h +++ b/drivers/net/wireless/realtek/rtlwifi/base.h @@ -120,7 +120,7 @@ void rtl_init_rx_config(struct ieee80211_hw *hw); void rtl_init_rfkill(struct ieee80211_hw *hw); void rtl_deinit_rfkill(struct ieee80211_hw *hw); -void rtl_watch_dog_timer_callback(unsigned long data); +void rtl_watch_dog_timer_callback(struct timer_list *t); void rtl_deinit_deferred_work(struct ieee80211_hw *hw); bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); @@ -169,7 +169,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); u8 rtl_tid_to_ac(u8 tid); -void rtl_easy_concurrent_retrytimer_callback(unsigned long data); +void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t); extern struct rtl_global_var rtl_global_var; void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c index 294a6b43d1bc..e025cb06443d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/core.c +++ b/drivers/net/wireless/realtek/rtlwifi/core.c @@ -160,7 +160,7 @@ static int rtl_op_start(struct ieee80211_hw *hw) mutex_lock(&rtlpriv->locks.conf_mutex); err = rtlpriv->intf_ops->adapter_start(hw); if (!err) - rtl_watch_dog_timer_callback((unsigned long)hw); + rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer); mutex_unlock(&rtlpriv->locks.conf_
Re: [PATCH v2] sctp: full support for ipv6 ip_nonlocal_bind & IP_FREEBIND
From: Laszlo Toth Date: Mon, 23 Oct 2017 19:19:33 +0200 > Commit 9b9742022888 ("sctp: support ipv6 nonlocal bind") > introduced support for the above options as v4 sctp did, > so patched sctp_v6_available(). > > In the v4 implementation it's enough, because > sctp_inet_bind_verify() just returns with sctp_v4_available(). > However sctp_inet6_bind_verify() has an extra check before that > for link-local scope_id, which won't respect the above options. > > Added the checks before calling ipv6_chk_addr(), but > not before the validation of scope_id. > > before (w/ both options): > ./v6test fe80::10 sctp > bind failed, errno: 99 (Cannot assign requested address) > ./v6test fe80::10 tcp > bind success, errno: 0 (Success) > > after (w/ both options): > ./v6test fe80::10 sctp > bind success, errno: 0 (Success) > > Signed-off-by: Laszlo Toth Applied.
Re: [net-next PATCH] bpf: cpumap fix potential lost wake-up problem
From: Jesper Dangaard Brouer Date: Mon, 23 Oct 2017 19:39:28 +0200 > As pointed out by Michael, commit 1c601d829ab0 ("bpf: cpumap xdp_buff > to skb conversion and allocation") contains a classical example of the > potential lost wake-up problem. > > We need to recheck the condition __ptr_ring_empty() after changing > current->state to TASK_INTERRUPTIBLE, this avoids a race between > wake_up_process() and schedule(). After this, a race with > wake_up_process() will simply change the state to TASK_RUNNING, and > the schedule() call not really put us to sleep. > > Fixes: 1c601d829ab0 ("bpf: cpumap xdp_buff to skb conversion and allocation") > Reported-by: "Michael S. Tsirkin" Applied.
Re: [PATCH] ethernet: cavium: octeon: Switch to using netdev_info().
From: "Steven J. Hill" Date: Mon, 23 Oct 2017 11:43:25 -0500 > @@ -705,14 +705,15 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device > *netdev, > u64 clock_comp = (NSEC_PER_SEC << 32) / > octeon_get_io_clock_rate(); > if (!ptp.s.ptp_en) > cvmx_write_csr(CVMX_MIO_PTP_CLOCK_COMP, > clock_comp); > - pr_info("PTP Clock: Using sclk reference at %lld Hz\n", > + netdev_info(netdev, > + "PTP Clock: Using sclk reference at %lld Hz\n", Please get the argument alignment correct when you make changes like this. For a function call, the arguments on the second and subsequent line of arguments must start exactly at the first column after the openning parenthesis of the call. You must use the appropriate number of TAB then SPACE characters necessary to achieve this. Thank you.
Re: [PATCH net-next] net: dsa: check master device before put
From: Vivien Didelot Date: Mon, 23 Oct 2017 14:01:41 -0400 > In the case of pdata, the dsa_cpu_parse function calls dev_put() before > making sure it isn't NULL. Fix this. > > Fixes: 71e0bbde0d88 ("net: dsa: Add support for platform data") > Signed-off-by: Vivien Didelot Please submit a 'net' version of this patch and then please patiently wait for it to be properly merged and propagated into 'net-next'. Thank you.
[PATCH net 3/3] net: mvpp2: do not sleep in set_rx_mode
This patch replaces GFP_KERNEL by GFP_ATOMIC to avoid sleeping in the ndo_set_rx_mode() call which is called with BH disabled. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart --- drivers/net/ethernet/marvell/mvpp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 5aa57c035ed8..a3231fe98384 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -3396,7 +3396,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da, struct mvpp2_prs_entry *pe; int tid; - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc(sizeof(*pe), GFP_ATOMIC); if (!pe) return NULL; mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); @@ -3458,7 +3458,7 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port, if (tid < 0) return tid; - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc(sizeof(*pe), GFP_ATOMIC); if (!pe) return -ENOMEM; mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); -- 2.14.2
RE: [PATCH] net: tipc: Convert timers to use timer_setup()
NAK. It doesn't sound like a good idea to send this to net. Especially since one of these timers has already been refactored in net-next. ///jon > -Original Message- > From: Kees Cook [mailto:keesc...@chromium.org] > Sent: Tuesday, October 24, 2017 10:47 > To: David S. Miller > Cc: Jon Maloy ; Ying Xue > ; netdev@vger.kernel.org; tipc- > discuss...@lists.sourceforge.net; linux-ker...@vger.kernel.org > Subject: [PATCH] net: tipc: Convert timers to use timer_setup() > > In preparation for unconditionally passing the struct timer_list pointer to > all > timer callbacks, switch to using the new timer_setup() and from_timer() to > pass the timer pointer explicitly. > > Cc: Jon Maloy > Cc: Ying Xue > Cc: "David S. Miller" > Cc: netdev@vger.kernel.org > Cc: tipc-discuss...@lists.sourceforge.net > Signed-off-by: Kees Cook > --- > net/tipc/discover.c | 6 +++--- > net/tipc/monitor.c | 6 +++--- > net/tipc/node.c | 8 > net/tipc/socket.c | 10 +- > net/tipc/subscr.c | 6 +++--- > 5 files changed, 18 insertions(+), 18 deletions(-) > > diff --git a/net/tipc/discover.c b/net/tipc/discover.c index > 02462d67d191..92e4828c6b09 100644 > --- a/net/tipc/discover.c > +++ b/net/tipc/discover.c > @@ -224,9 +224,9 @@ void tipc_disc_remove_dest(struct tipc_link_req > *req) > * > * Called whenever a link setup request timer associated with a bearer > expires. > */ > -static void disc_timeout(unsigned long data) > +static void disc_timeout(struct timer_list *t) > { > - struct tipc_link_req *req = (struct tipc_link_req *)data; > + struct tipc_link_req *req = from_timer(req, t, timer); > struct sk_buff *skb; > int max_delay; > > @@ -292,7 +292,7 @@ int tipc_disc_create(struct net *net, struct > tipc_bearer *b, > req->num_nodes = 0; > req->timer_intv = TIPC_LINK_REQ_INIT; > spin_lock_init(&req->lock); > - setup_timer(&req->timer, disc_timeout, (unsigned long)req); > + timer_setup(&req->timer, disc_timeout, 0); > mod_timer(&req->timer, jiffies + req->timer_intv); > b->link_req = req; > *skb = skb_clone(req->buf, GFP_ATOMIC); diff --git > a/net/tipc/monitor.c b/net/tipc/monitor.c index > 9e109bb1a207..b9c32557d73c 100644 > --- a/net/tipc/monitor.c > +++ b/net/tipc/monitor.c > @@ -578,9 +578,9 @@ void tipc_mon_get_state(struct net *net, u32 addr, > read_unlock_bh(&mon->lock); > } > > -static void mon_timeout(unsigned long m) > +static void mon_timeout(struct timer_list *t) > { > - struct tipc_monitor *mon = (void *)m; > + struct tipc_monitor *mon = from_timer(mon, t, timer); > struct tipc_peer *self; > int best_member_cnt = dom_size(mon->peer_cnt) - 1; > > @@ -623,7 +623,7 @@ int tipc_mon_create(struct net *net, int bearer_id) > self->is_up = true; > self->is_head = true; > INIT_LIST_HEAD(&self->list); > - setup_timer(&mon->timer, mon_timeout, (unsigned long)mon); > + timer_setup(&mon->timer, mon_timeout, 0); > mon->timer_intv = msecs_to_jiffies(MON_TIMEOUT + (tn->random > & 0x)); > mod_timer(&mon->timer, jiffies + mon->timer_intv); > return 0; > diff --git a/net/tipc/node.c b/net/tipc/node.c index > 89f8ac73bf65..009a81631280 100644 > --- a/net/tipc/node.c > +++ b/net/tipc/node.c > @@ -153,7 +153,7 @@ static void tipc_node_link_down(struct tipc_node *n, > int bearer_id, > bool delete); > static void node_lost_contact(struct tipc_node *n, struct sk_buff_head > *inputq); static void tipc_node_delete(struct tipc_node *node); -static void > tipc_node_timeout(unsigned long data); > +static void tipc_node_timeout(struct timer_list *t); > static void tipc_node_fsm_evt(struct tipc_node *n, int evt); static struct > tipc_node *tipc_node_find(struct net *net, u32 addr); static void > tipc_node_put(struct tipc_node *node); @@ -361,7 +361,7 @@ struct > tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities) > goto exit; > } > tipc_node_get(n); > - setup_timer(&n->timer, tipc_node_timeout, (unsigned long)n); > + timer_setup(&n->timer, tipc_node_timeout, 0); > n->keepalive_intv = U32_MAX; > hlist_add_head_rcu(&n->hash, &tn- > >node_htable[tipc_hashfn(addr)]); > list_for_each_entry_rcu(temp_node, &tn->node_list, list) { @@ - > 500,9 +500,9 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, > u32 port) > > /* tipc_node_timeout - handle expiration of node timer > */ > -static void tipc_node_timeout(unsigned long data) > +static void tipc_node_timeout(struct timer_list *t) > { > - struct tipc_node *n = (struct tipc_node *)data; > + struct tipc_node *n = from_timer(n, t, timer); > struct tipc_link_entry *le; > struct sk_buff_head xmitq; > int bearer_id; > diff --git a/net/tipc/socket.c b/net/tipc/socket.c index > b3b72d8e9543..6387839f643d 100644 > --- a/net/tipc/socket.c > +++ b/net/tipc/socket.c > @@ -125,7 +125,7
Re: [PATCH] ipv4: tcp_minisocks: use BUG_ON instead of if condition followed by BUG
From: "Gustavo A. R. Silva" Date: Mon, 23 Oct 2017 13:10:56 -0500 > Use BUG_ON instead of if condition followed by BUG in tcp_time_wait. > > This issue was detected with the help of Coccinelle. > > Signed-off-by: Gustavo A. R. Silva Applied.
Re: [PATCH] ipv4: icmp: use BUG_ON instead of if condition followed by BUG
From: "Gustavo A. R. Silva" Date: Mon, 23 Oct 2017 13:08:14 -0500 > Use BUG_ON instead of if condition followed by BUG in icmp_timestamp. > > This issue was detected with the help of Coccinelle. > > Signed-off-by: Gustavo A. R. Silva Applied.
Re: [PATCH v3] net/sock: Update sk rcu iterator macro.
From: Tim Hansen Date: Mon, 23 Oct 2017 15:35:58 -0400 > Mark hlist node in sk rcu iterator as protected by the rcu. > hlist_next_rcu accomplishes this and silences the warnings > sparse throws. > > Found with make C=1 net/ipv4/udp.o on linux-next tag > next-20171009. > > Signed-off-by: Tim Hansen Applied.
[PATCH net 1/3] net: mvpp2: fix typo in the tcam setup
This patch fixes a typo in the mvpp2_prs_tcam_data_cmp() function, as the shift value is inverted with the data. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart --- drivers/net/ethernet/marvell/mvpp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 8621e835f362..2b79b570f4e5 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -1539,7 +1539,7 @@ static bool mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offs, int off = MVPP2_PRS_TCAM_DATA_BYTE(offs); u16 tcam_data; - tcam_data = (8 << pe->tcam.byte[off + 1]) | pe->tcam.byte[off]; + tcam_data = (pe->tcam.byte[off + 1] << 8) | pe->tcam.byte[off]; if (tcam_data != data) return false; return true; -- 2.14.2
[PATCH net 2/3] net: mvpp2: fix invalid parameters order when calling the tcam init
When calling mvpp2_prs_mac_multi_set() from mvpp2_prs_mac_init(), two parameters (the port index and the table index) are inverted. Fixes this. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart --- drivers/net/ethernet/marvell/mvpp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 2b79b570f4e5..5aa57c035ed8 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -2614,8 +2614,8 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv) /* place holders only - no ports */ mvpp2_prs_mac_drop_all_set(priv, 0, false); mvpp2_prs_mac_promisc_set(priv, 0, false); - mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_ALL, 0, false); - mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_IP6, 0, false); + mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_ALL, false); + mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_IP6, false); } /* Set default entries for various types of dsa packets */ -- 2.14.2
Re: [PATCH net-next] ipv6: add ip6_null_entry check in rt6_select()
From: Wei Wang Date: Mon, 23 Oct 2017 14:59:35 -0700 > From: Wei Wang > > In rt6_select(), fn->leaf could be pointing to net->ipv6.ip6_null_entry. > In this case, we should directly return instead of trying to carry on > with the rest of the process. > If not, we could crash at: > spin_lock_bh(&leaf->rt6i_table->rt6_lock); > because net->ipv6.ip6_null_entry does not have rt6i_table set. ... > Fixes: 66f5d6ce53e6 ("ipv6: replace rwlock with rcu and spinlock in > fib6_table") > Signed-off-by: Wei Wang > Acked-by: Eric Dumazet Applied, thanks.
Re: [PATCH v2 net] tcp/dccp: fix other lockdep splats accessing ireq_opt
From: Eric Dumazet Date: Mon, 23 Oct 2017 16:15:08 -0700 > +static inline struct ip_options_rcu *ireq_opt_deref(const struct > inet_request_sock *ireq) > +{ > + return rcu_dereference_check(ireq->ireq_opt, > + refcount_read(&ireq.req->rsk_refcnt) > 0); ^ Eric, _please_ build test your changes properly.
Re: [PATCH V3 net-next] liquidio: pass date and time info to NIC firmware
From: Felix Manlunas Date: Mon, 23 Oct 2017 20:33:25 -0700 > From: Veerasenareddy Burru > > Pass date and time information to NIC at the time of loading > firmware and periodically update the host time to NIC firmware. > This is to make NIC firmware use the same time reference as Host, > so that it is easy to correlate logs from firmware and host for debugging. > > Signed-off-by: Veerasenareddy Burru > Signed-off-by: Felix Manlunas Applied.
Re: [PATCH net-next] net/sched: Fix actions list corruption when adding offloaded tc flows
From: Or Gerlitz Date: Tue, 24 Oct 2017 08:58:02 +0300 > Prior to commit b3f55bdda8df, the networking core doesn't wire an in-place > actions list the when the low level driver is called to offload the flow, > but all low level drivers do that (call tcf_exts_to_list()) in their > offloading "add" logic. > > Now, the in-place list is set in the core which goes over the list in a loop, > but also by the hw driver when their offloading code is invoked indirectly: > > cls_xxx add flow -> tc_setup_cb_call -> tc_exts_setup_cb_egdev_call -> > hw driver > > which messes up the core list instance upon driver return. Fix that by > avoiding > in-place list on the net core code that deals with adding flows. > > Fixes: b3f55bdda8df ('net: sched: introduce per-egress action device > callbacks') > Signed-off-by: Or Gerlitz > Acked-by: Jiri Pirko Applied.
Re: [patch net-next] mlxsw: spectrum_dpipe: Fix entries dump of the adjacency table
From: Jiri Pirko Date: Tue, 24 Oct 2017 10:11:42 +0200 > From: Arkadi Sharshevsky > > During the dump the per netlink packet entry counter should be zeroed out > when new packet is created. > > Fixes: 190d38a52a73 ("mlxsw: spectrum_dpipe: Add support for adjacency table > dump") > Signed-off-by: Arkadi Sharshevsky > Reported-by: David Ahern > Signed-off-by: Jiri Pirko Applied.
Re: [patch net-next 0/3] mlxsw: Various fixes
From: Jiri Pirko Date: Tue, 24 Oct 2017 11:17:14 +0200 > From: Jiri Pirko > > Yotam says: > > Cleanup some issues reported by sparse. Series applied.
[PATCH net-next 1/2] net: updating dst lastusage is an unlikely event.
Since commit 0da4af00b2ed ("ipv6: only update __use and lastusetime once per jiffy at most"), updating the dst lastuse field is an unlikely action: it happens at most once per jiffy, out of potentially millions of calls per second. Mark explicitly the code as such, and let the compiler generate better code. Note: gcc 7.2 and several older versions do actually generate different - better - code when the unlikely() hint is in place, avoid jump in the fast path and keeping better code locality. Signed-off-by: Paolo Abeni --- include/net/dst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/dst.h b/include/net/dst.h index d70b33dc2332..0744a9630eed 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -257,7 +257,7 @@ static inline void dst_hold(struct dst_entry *dst) static inline void dst_use_noref(struct dst_entry *dst, unsigned long time) { - if (time != dst->lastuse) { + if (unlikely(time != dst->lastuse)) { dst->__use++; dst->lastuse = time; } -- 2.13.6
[PATCH 1/2] ipsec: Fix dst leak in xfrm_bundle_create().
From: David Miller If we cannot find a suitable inner_mode value, we will leak the currently allocated 'xdst'. The fix is to make sure it is linked into the chain before erroring out. Signed-off-by: David S. Miller Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_policy.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f062539..2746b62 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1573,6 +1573,14 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, goto put_states; } + if (!dst_prev) + dst0 = dst1; + else + /* Ref count is taken during xfrm_alloc_dst() +* No need to do dst_clone() on dst1 +*/ + dst_prev->child = dst1; + if (xfrm[i]->sel.family == AF_UNSPEC) { inner_mode = xfrm_ip2inner_mode(xfrm[i], xfrm_af2proto(family)); @@ -1584,14 +1592,6 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, } else inner_mode = xfrm[i]->inner_mode; - if (!dst_prev) - dst0 = dst1; - else - /* Ref count is taken during xfrm_alloc_dst() -* No need to do dst_clone() on dst1 -*/ - dst_prev->child = dst1; - xdst->route = dst; dst_copy_metrics(dst1, dst); -- 2.7.4
[PATCH 2/2] ipsec: Fix aborted xfrm policy dump crash
From: Herbert Xu An independent security researcher, Mohamed Ghannam, has reported this vulnerability to Beyond Security's SecuriTeam Secure Disclosure program. The xfrm_dump_policy_done function expects xfrm_dump_policy to have been called at least once or it will crash. This can be triggered if a dump fails because the target socket's receive buffer is full. This patch fixes it by using the cb->start mechanism to ensure that the initialisation is always done regardless of the buffer situation. Fixes: 12a169e7d8f4 ("ipsec: Put dumpers on the dump list") Signed-off-by: Herbert Xu Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_user.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b997f13..e44a0fe 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1693,32 +1693,34 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr static int xfrm_dump_policy_done(struct netlink_callback *cb) { - struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; struct net *net = sock_net(cb->skb->sk); xfrm_policy_walk_done(walk, net); return 0; } +static int xfrm_dump_policy_start(struct netlink_callback *cb) +{ + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; + + BUILD_BUG_ON(sizeof(*walk) > sizeof(cb->args)); + + xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); + return 0; +} + static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); - struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; struct xfrm_dump_info info; - BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) > -sizeof(cb->args) - sizeof(cb->args[0])); - info.in_skb = cb->skb; info.out_skb = skb; info.nlmsg_seq = cb->nlh->nlmsg_seq; info.nlmsg_flags = NLM_F_MULTI; - if (!cb->args[0]) { - cb->args[0] = 1; - xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); - } - (void) xfrm_policy_walk(net, walk, dump_one_policy, &info); return skb->len; @@ -2474,6 +2476,7 @@ static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { static const struct xfrm_link { int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); + int (*start)(struct netlink_callback *); int (*dump)(struct sk_buff *, struct netlink_callback *); int (*done)(struct netlink_callback *); const struct nla_policy *nla_pol; @@ -2487,6 +2490,7 @@ static const struct xfrm_link { [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy}, [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy}, [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, + .start = xfrm_dump_policy_start, .dump = xfrm_dump_policy, .done = xfrm_dump_policy_done }, [XFRM_MSG_ALLOCSPI- XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, @@ -2539,6 +2543,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, { struct netlink_dump_control c = { + .start = link->start, .dump = link->dump, .done = link->done, }; -- 2.7.4
pull request (net): ipsec 2017-10-24
1) Fix a memleak when we don't find a inner_mode during bundle creation. From David Miller. 2) Fix a xfrm policy dump crash. We may crash on error when dumping policies via netlink. Fix this by initializing the policy walk with the cb->start method. This fix is a serious stable candidate. From Herbert Xu. Please pull or let me know if there are problems. Thanks! The following changes since commit c0576e3975084d4699b7bfef578613fb8e1144f6: net: call cgroup_sk_alloc() earlier in sk_clone_lock() (2017-10-10 20:24:29 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git master for you to fetch changes up to 1137b5e2529a8f5ca8ee709288ecba3e68044df2: ipsec: Fix aborted xfrm policy dump crash (2017-10-23 09:35:48 +0200) David Miller (1): ipsec: Fix dst leak in xfrm_bundle_create(). Herbert Xu (1): ipsec: Fix aborted xfrm policy dump crash net/xfrm/xfrm_policy.c | 16 net/xfrm/xfrm_user.c | 25 +++-- 2 files changed, 23 insertions(+), 18 deletions(-)
Re: [PATCH net-next 1/2] net: updating dst lastusage is an unlikely event.
On Tue, 2017-10-24 at 12:37 +0200, Paolo Abeni wrote: > Since commit 0da4af00b2ed ("ipv6: only update __use and lastusetime > once per jiffy at most"), updating the dst lastuse field is an > unlikely action: it happens at most once per jiffy, out of > potentially millions of calls per second. > > Mark explicitly the code as such, and let the compiler generate > better code. > > Note: gcc 7.2 and several older versions do actually generate > different - better - code when the unlikely() hint is in place, > avoid jump in the fast path and keeping better code locality. > > Signed-off-by: Paolo Abeni Oops, I placed a bad subject prefix here, please ignore. I'll resend soon with a proper one. Sorry for the noise, Paolo
[PATCH net-next] net: updating dst lastusage is an unlikely event.
Since commit 0da4af00b2ed ("ipv6: only update __use and lastusetime once per jiffy at most"), updating the dst lastuse field is an unlikely action: it happens at most once per jiffy, out of potentially millions of calls per second. Mark explicitly the code as such, and let the compiler generate better code. Note: gcc 7.2 and several older versions do actually generate different - better - code when the unlikely() hint is in place, avoid jump in the fast path and keeping better code locality. Signed-off-by: Paolo Abeni --- include/net/dst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/dst.h b/include/net/dst.h index d70b33dc2332..0744a9630eed 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -257,7 +257,7 @@ static inline void dst_hold(struct dst_entry *dst) static inline void dst_use_noref(struct dst_entry *dst, unsigned long time) { - if (time != dst->lastuse) { + if (unlikely(time != dst->lastuse)) { dst->__use++; dst->lastuse = time; } -- 2.13.6
Re: [PATCH] drivers/net: sis: Convert timers to use timer_setup()
On 24 October 2017 10:46:52 CEST, Kees Cook wrote: >In preparation for unconditionally passing the struct timer_list >pointer to >all timer callbacks, switch to using the new timer_setup() and >from_timer() >to pass the timer pointer explicitly. > >Cc: Francois Romieu >Cc: Daniele Venzano >Cc: netdev@vger.kernel.org >Signed-off-by: Kees Cook Signed-off-by: Daniele Venzano >--- > drivers/net/ethernet/sis/sis190.c | 10 -- > drivers/net/ethernet/sis/sis900.c | 10 +- > 2 files changed, 9 insertions(+), 11 deletions(-) > >diff --git a/drivers/net/ethernet/sis/sis190.c >b/drivers/net/ethernet/sis/sis190.c >index 445109bd6910..c2c50522b96d 100644 >--- a/drivers/net/ethernet/sis/sis190.c >+++ b/drivers/net/ethernet/sis/sis190.c >@@ -1018,10 +1018,10 @@ static void sis190_phy_task(struct work_struct >*work) > rtnl_unlock(); > } > >-static void sis190_phy_timer(unsigned long __opaque) >+static void sis190_phy_timer(struct timer_list *t) > { >- struct net_device *dev = (struct net_device *)__opaque; >- struct sis190_private *tp = netdev_priv(dev); >+ struct sis190_private *tp = from_timer(tp, t, timer); >+ struct net_device *dev = tp->dev; > > if (likely(netif_running(dev))) > schedule_work(&tp->phy_task); >@@ -1039,10 +1039,8 @@ static inline void sis190_request_timer(struct >net_device *dev) > struct sis190_private *tp = netdev_priv(dev); > struct timer_list *timer = &tp->timer; > >- init_timer(timer); >+ timer_setup(timer, sis190_phy_timer, 0); > timer->expires = jiffies + SIS190_PHY_TIMEOUT; >- timer->data = (unsigned long)dev; >- timer->function = sis190_phy_timer; > add_timer(timer); > } > >diff --git a/drivers/net/ethernet/sis/sis900.c >b/drivers/net/ethernet/sis/sis900.c >index cb61247b0526..4bb89f74742c 100644 >--- a/drivers/net/ethernet/sis/sis900.c >+++ b/drivers/net/ethernet/sis/sis900.c >@@ -218,7 +218,7 @@ static void sis900_init_rxfilter (struct net_device >* net_dev); > static u16 read_eeprom(void __iomem *ioaddr, int location); >static int mdio_read(struct net_device *net_dev, int phy_id, int >location); >static void mdio_write(struct net_device *net_dev, int phy_id, int >location, int val); >-static void sis900_timer(unsigned long data); >+static void sis900_timer(struct timer_list *t); >static void sis900_check_mode (struct net_device *net_dev, struct >mii_phy *mii_phy); > static void sis900_tx_timeout(struct net_device *net_dev); > static void sis900_init_tx_ring(struct net_device *net_dev); >@@ -1065,7 +1065,7 @@ sis900_open(struct net_device *net_dev) > > /* Set the timer to switch to check for link beat and perhaps switch > to an alternate media type. */ >- setup_timer(&sis_priv->timer, sis900_timer, (unsigned long)net_dev); >+ timer_setup(&sis_priv->timer, sis900_timer, 0); > sis_priv->timer.expires = jiffies + HZ; > add_timer(&sis_priv->timer); > >@@ -1300,10 +1300,10 @@ static void sis630_set_eq(struct net_device >*net_dev, u8 revision) > *link status (ON/OFF) and link mode (10/100/Full/Half) > */ > >-static void sis900_timer(unsigned long data) >+static void sis900_timer(struct timer_list *t) > { >- struct net_device *net_dev = (struct net_device *)data; >- struct sis900_private *sis_priv = netdev_priv(net_dev); >+ struct sis900_private *sis_priv = from_timer(sis_priv, t, timer); >+ struct net_device *net_dev = sis_priv->mii_info.dev; > struct mii_phy *mii_phy = sis_priv->mii; > static const int next_tick = 5*HZ; > int speed = 0, duplex = 0;
[PATCH net-next] ipv6: update use count on dst_check()
Currently, the dst 'lastuse' field is not updated in a reliable way for dst entries only accessed via socket cache. This may fool the ipv6 dst gc, especially since we really age out unused entries, either via the commit 1859bac04fb6 ("ipv6: remove from fib tree aged out RTF_CACHE dst") or via the commit 1e2ea8ad37be ("ipv6: set dst.obsolete when a cached route has expired"). Updating such field is now very cheap, thanks to commit 0da4af00b2ed ("ipv6: only update __use and lastusetime once per jiffy at most"), so we can address the issue updating 'lastuse' in ip6_dst_check(), if successful. Fixes: 1859bac04fb6 ("ipv6: remove from fib tree aged out RTF_CACHE dst") Fixes: 1e2ea8ad37be ("ipv6: set dst.obsolete when a cached route has expired") Signed-off-by: Paolo Abeni --- net/ipv6/route.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 87a15cbd0e8b..8f8c7fb83b9b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1952,6 +1952,7 @@ static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie) if (rt6_check_expired(rt)) return NULL; + dst_use_noref(&rt->dst, jiffies); return &rt->dst; } -- 2.13.6
Re: [patch net-next] net: core: introduce mini_Qdisc and eliminate usage of tp->q for clsact fastpath
On 10/23/2017 11:28 PM, Jiri Pirko wrote: [...] diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 031dffd..c7ddbdb 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -143,6 +143,36 @@ static inline int qdisc_avail_bulklimit(const struct netdev_queue *txq) #endif } +/* Mini Qdisc serves for specific needs of ingress/clsact Qdisc. + * The fast path only needs to access filter list and to update stats + */ +struct mini_Qdisc { + struct tcf_proto __rcu *filter_list; + struct gnet_stats_basic_cpu __percpu *cpu_bstats; + struct gnet_stats_queue __percpu *cpu_qstats; + struct mini_Qdisc __rcu **p_miniq; +}; + +static inline void mini_qdisc_init(struct mini_Qdisc *miniq, + struct Qdisc *qdisc, + struct mini_Qdisc __rcu **p_miniq) +{ + miniq->cpu_bstats = qdisc->cpu_bstats; + miniq->cpu_qstats = qdisc->cpu_qstats; + miniq->p_miniq = p_miniq; +} + +static inline void mini_qdisc_enable(struct mini_Qdisc *miniq) +{ + rcu_assign_pointer(*miniq->p_miniq, miniq); +} + +static inline void mini_qdisc_disable(struct mini_Qdisc *miniq) +{ + RCU_INIT_POINTER(*miniq->p_miniq, NULL); + rcu_barrier(); Can you add a comment against which call_rcu() above barrier protects against? +} + struct Qdisc_class_ops { /* Child qdisc manipulation */ struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); @@ -259,9 +289,13 @@ struct qdisc_skb_cb { unsigned char data[QDISC_CB_PRIV_LEN]; }; +typedef void tcf_chain_change_empty_t(struct tcf_proto __rcu **p_filter_chain, + bool empty); + struct tcf_chain { struct tcf_proto __rcu *filter_chain; struct tcf_proto __rcu **p_filter_chain; + tcf_chain_change_empty_t *chain_change_empty; struct list_head list; struct tcf_block *block; u32 index; /* chain index */ @@ -605,6 +639,12 @@ static inline void qdisc_bstats_cpu_update(struct Qdisc *sch, bstats_cpu_update(this_cpu_ptr(sch->cpu_bstats), skb); } +static inline void mini_qdisc_bstats_cpu_update(struct mini_Qdisc *miniq, + const struct sk_buff *skb) +{ + bstats_cpu_update(this_cpu_ptr(miniq->cpu_bstats), skb); +} + static inline void qdisc_bstats_update(struct Qdisc *sch, const struct sk_buff *skb) { @@ -648,6 +688,11 @@ static inline void qdisc_qstats_cpu_drop(struct Qdisc *sch) this_cpu_inc(sch->cpu_qstats->drops); } +static inline void mini_qdisc_qstats_cpu_drop(struct mini_Qdisc *miniq) +{ + this_cpu_inc(miniq->cpu_qstats->drops); +} + static inline void qdisc_qstats_overlimit(struct Qdisc *sch) { sch->qstats.overlimits++; diff --git a/net/core/dev.c b/net/core/dev.c index 24ac908..b4a5812 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3274,14 +3274,16 @@ EXPORT_SYMBOL(dev_loopback_xmit); static struct sk_buff * sch_handle_egress(struct sk_buff *skb, int *ret, struct net_device *dev) { - struct tcf_proto *cl = rcu_dereference_bh(dev->egress_cl_list); + struct mini_Qdisc *miniq = rcu_dereference_bh(skb->dev->miniq_egress); We already have dev passed here, so lets use it as done previously. struct tcf_result cl_res; + struct tcf_proto *cl; - if (!cl) + if (!miniq) return skb; + cl = rcu_dereference_bh(miniq->filter_list); This one still has two RCU dereferences instead of just one. Could we bind the lifetime of the miniq 1:1 to the filter_list head such that we can then also get rid of the 2nd rcu_dereference_bh() and piggy-back on the first one for the filter_list there, thus we push this into control slow-path instead? /* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */ - qdisc_bstats_cpu_update(cl->q, skb); + mini_qdisc_bstats_cpu_update(miniq, skb); switch (tcf_classify(skb, cl, &cl_res, false)) { case TC_ACT_OK: @@ -3289,7 +3291,7 @@ sch_handle_egress(struct sk_buff *skb, int *ret, struct net_device *dev) skb->tc_index = TC_H_MIN(cl_res.classid); break; case TC_ACT_SHOT: - qdisc_qstats_cpu_drop(cl->q); + mini_qdisc_qstats_cpu_drop(miniq); *ret = NET_XMIT_DROP; kfree_skb(skb); return NULL; @@ -4189,16 +4191,19 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, struct net_device *orig_dev) { #ifdef CONFIG_NET_CLS_ACT - struct tcf_proto *cl = rcu_dereference_bh(skb->dev->ingress_cl_list); + struct mini_Qdisc *miniq = rcu_dereference_bh(skb->dev->miniq_ingress); struct tcf_result cl_res; + struct tcf_proto *cl; /* If there's at least one ingress present somewhere
Re: pull request (net): ipsec 2017-10-24
From: Steffen Klassert Date: Tue, 24 Oct 2017 12:37:38 +0200 > 1) Fix a memleak when we don't find a inner_mode >during bundle creation. From David Miller. > > 2) Fix a xfrm policy dump crash. We may crash >on error when dumping policies via netlink. >Fix this by initializing the policy walk >with the cb->start method. This fix is a >serious stable candidate. From Herbert Xu. > > Please pull or let me know if there are problems. Pulled, please submit #2 to -stable indeed!
pull-request: can 2017-10-24
Hello David, here's another pull request for net/master. The patch by Gerhard Bertelsmann fixes the CAN_CTRLMODE_LOOPBACK in the sun4i driver. Two patches by Jimmy Assarsson for the kvaser_usb driver fix a print in the error path of the kvaser_usb_close() and remove a wrong warning message with the Leaf v2 firmware version v4.1.844. regards, Marc --- The following changes since commit b71d21c274eff20a9db8158882b545b141b73ab8: sctp: full support for ipv6 ip_nonlocal_bind & IP_FREEBIND (2017-10-24 18:39:46 +0900) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git tags/linux-can-fixes-for-4.14-20171024 for you to fetch changes up to e1d2d1329a5722dbecc9c278303fcc4aa01f8790: can: kvaser_usb: Ignore CMD_FLUSH_QUEUE_REPLY messages (2017-10-24 13:00:36 +0200) linux-can-fixes-for-4.14-20171024 Gerhard Bertelsmann (1): can: sun4i: fix loopback mode Jimmy Assarsson (2): can: kvaser_usb: Correct return value in printout can: kvaser_usb: Ignore CMD_FLUSH_QUEUE_REPLY messages drivers/net/can/sun4i_can.c | 3 +-- drivers/net/can/usb/kvaser_usb.c | 9 - 2 files changed, 9 insertions(+), 3 deletions(-)
[PATCH 1/3] can: sun4i: fix loopback mode
From: Gerhard Bertelsmann Fix loopback mode by setting the right flag and remove presume mode. Signed-off-by: Gerhard Bertelsmann Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sun4i_can.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 68ef0a4cd821..b0c80859f746 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -342,7 +342,7 @@ static int sun4i_can_start(struct net_device *dev) /* enter the selected mode */ mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR); - if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK) + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE; else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE; @@ -811,7 +811,6 @@ static int sun4ican_probe(struct platform_device *pdev) priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_LOOPBACK | - CAN_CTRLMODE_PRESUME_ACK | CAN_CTRLMODE_3_SAMPLES; priv->base = addr; priv->clk = clk; -- 2.14.2
[PATCH 2/3] can: kvaser_usb: Correct return value in printout
From: Jimmy Assarsson If the return value from kvaser_usb_send_simple_msg() was non-zero, the return value from kvaser_usb_flush_queue() was printed in the kernel warning. Signed-off-by: Jimmy Assarsson Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 18cc529fb807..861e90efab86 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1609,7 +1609,8 @@ static int kvaser_usb_close(struct net_device *netdev) if (err) netdev_warn(netdev, "Cannot flush queue, error %d\n", err); - if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel)) + err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel); + if (err) netdev_warn(netdev, "Cannot reset card, error %d\n", err); err = kvaser_usb_stop_chip(priv); -- 2.14.2
[PATCH 3/3] can: kvaser_usb: Ignore CMD_FLUSH_QUEUE_REPLY messages
From: Jimmy Assarsson To avoid kernel warning "Unhandled message (68)", ignore the CMD_FLUSH_QUEUE_REPLY message for now. As of Leaf v2 firmware version v4.1.844 (2017-02-15), flush tx queue is synchronous. There is a capability bit indicating whether flushing tx queue is synchronous or asynchronous. A proper solution would be to query the device for capabilities. If the synchronous tx flush capability bit is set, we should wait for CMD_FLUSH_QUEUE_REPLY message, while flushing the tx queue. Signed-off-by: Jimmy Assarsson Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 861e90efab86..9b18d96ef526 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -137,6 +137,7 @@ static inline bool kvaser_is_usbcan(const struct usb_device_id *id) #define CMD_RESET_ERROR_COUNTER49 #define CMD_TX_ACKNOWLEDGE 50 #define CMD_CAN_ERROR_EVENT51 +#define CMD_FLUSH_QUEUE_REPLY 68 #define CMD_LEAF_USB_THROTTLE 77 #define CMD_LEAF_LOG_MESSAGE 106 @@ -1301,6 +1302,11 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, goto warn; break; + case CMD_FLUSH_QUEUE_REPLY: + if (dev->family != KVASER_LEAF) + goto warn; + break; + default: warn: dev_warn(dev->udev->dev.parent, "Unhandled message (%d)\n", msg->id); -- 2.14.2
Re: pull request (net): ipsec 2017-10-24
On Tue, Oct 24, 2017 at 08:18:32PM +0900, David Miller wrote: > From: Steffen Klassert > Date: Tue, 24 Oct 2017 12:37:38 +0200 > > > 1) Fix a memleak when we don't find a inner_mode > >during bundle creation. From David Miller. > > > > 2) Fix a xfrm policy dump crash. We may crash > >on error when dumping policies via netlink. > >Fix this by initializing the policy walk > >with the cb->start method. This fix is a > >serious stable candidate. From Herbert Xu. > > > > Please pull or let me know if there are problems. > > Pulled, please submit #2 to -stable indeed! I can do so, but whenever I sent something networking related to -stable, it was ignored. I think this is because Greg expects that you do the stable submissions for networking.
Re: pull request (net): ipsec 2017-10-24
From: Steffen Klassert Date: Tue, 24 Oct 2017 13:35:25 +0200 > On Tue, Oct 24, 2017 at 08:18:32PM +0900, David Miller wrote: >> From: Steffen Klassert >> Date: Tue, 24 Oct 2017 12:37:38 +0200 >> >> > 1) Fix a memleak when we don't find a inner_mode >> >during bundle creation. From David Miller. >> > >> > 2) Fix a xfrm policy dump crash. We may crash >> >on error when dumping policies via netlink. >> >Fix this by initializing the policy walk >> >with the cb->start method. This fix is a >> >serious stable candidate. From Herbert Xu. >> > >> > Please pull or let me know if there are problems. >> >> Pulled, please submit #2 to -stable indeed! > > I can do so, but whenever I sent something networking related > to -stable, it was ignored. I think this is because Greg expects > that you do the stable submissions for networking. Send it, CC: me, and I'll reply making sure Greg knows. Thanks.
Re: [PATCH v2 net] tcp/dccp: fix other lockdep splats accessing ireq_opt
Hi Eric, [auto build test ERROR on net/master] url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/tcp-dccp-fix-other-lockdep-splats-accessing-ireq_opt/20171024-200038 config: i386-randconfig-x003-201743 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from include/linux/srcu.h:33:0, from include/linux/notifier.h:15, from include/linux/memory_hotplug.h:6, from include/linux/mmzone.h:779, from include/linux/gfp.h:5, from include/linux/mm.h:9, from net/socket.c:61: include/net/inet_sock.h: In function 'ireq_opt_deref': >> include/net/inet_sock.h:138:29: error: 'ireq' is a pointer; did you mean to >> use '->'? refcount_read(&ireq.req->rsk_refcnt) > 0); ^ -> include/linux/rcupdate.h:292:52: note: in definition of macro 'RCU_LOCKDEP_WARN' if (debug_lockdep_rcu_enabled() && !__warned && (c)) { \ ^ include/linux/rcupdate.h:486:2: note: in expansion of macro '__rcu_dereference_check' __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) ^~~ >> include/net/inet_sock.h:137:9: note: in expansion of macro >> 'rcu_dereference_check' return rcu_dereference_check(ireq->ireq_opt, ^ vim +138 include/net/inet_sock.h 134 135 static inline struct ip_options_rcu *ireq_opt_deref(const struct inet_request_sock *ireq) 136 { > 137 return rcu_dereference_check(ireq->ireq_opt, > 138 > refcount_read(&ireq.req->rsk_refcnt) > 0); 139 } 140 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v2 net] tcp/dccp: fix other lockdep splats accessing ireq_opt
Hi Eric, [auto build test WARNING on net/master] url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/tcp-dccp-fix-other-lockdep-splats-accessing-ireq_opt/20171024-200038 config: i386-randconfig-x079-201743 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/list.h:4, from include/linux/module.h:9, from net//8021q/vlan_dev.c:25: include/net/inet_sock.h: In function 'ireq_opt_deref': include/net/inet_sock.h:138:29: error: 'ireq' is a pointer; did you mean to use '->'? refcount_read(&ireq.req->rsk_refcnt) > 0); ^ -> include/linux/compiler.h:156:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ include/linux/rcupdate.h:292:3: note: in expansion of macro 'if' if (debug_lockdep_rcu_enabled() && !__warned && (c)) { \ ^~ >> include/linux/rcupdate.h:350:2: note: in expansion of macro >> 'RCU_LOCKDEP_WARN' RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \ ^~~~ include/linux/rcupdate.h:486:2: note: in expansion of macro '__rcu_dereference_check' __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) ^~~ include/net/inet_sock.h:137:9: note: in expansion of macro 'rcu_dereference_check' return rcu_dereference_check(ireq->ireq_opt, ^ include/net/inet_sock.h:138:29: error: 'ireq' is a pointer; did you mean to use '->'? refcount_read(&ireq.req->rsk_refcnt) > 0); ^ -> include/linux/compiler.h:156:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ include/linux/rcupdate.h:292:3: note: in expansion of macro 'if' if (debug_lockdep_rcu_enabled() && !__warned && (c)) { \ ^~ >> include/linux/rcupdate.h:350:2: note: in expansion of macro >> 'RCU_LOCKDEP_WARN' RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \ ^~~~ include/linux/rcupdate.h:486:2: note: in expansion of macro '__rcu_dereference_check' __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) ^~~ include/net/inet_sock.h:137:9: note: in expansion of macro 'rcu_dereference_check' return rcu_dereference_check(ireq->ireq_opt, ^ include/net/inet_sock.h:138:29: error: 'ireq' is a pointer; did you mean to use '->'? refcount_read(&ireq.req->rsk_refcnt) > 0); ^ -> include/linux/compiler.h:167:16: note: in definition of macro '__trace_if' __r = !!(cond); \ ^~~~ include/linux/rcupdate.h:292:3: note: in expansion of macro 'if' if (debug_lockdep_rcu_enabled() && !__warned && (c)) { \ ^~ >> include/linux/rcupdate.h:350:2: note: in expansion of macro >> 'RCU_LOCKDEP_WARN' RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \ ^~~~ include/linux/rcupdate.h:486:2: note: in expansion of macro '__rcu_dereference_check' __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu) ^~~ include/net/inet_sock.h:137:9: note: in expansion of macro 'rcu_dereference_check' return rcu_dereference_check(ireq->ireq_opt, ^ vim +/RCU_LOCKDEP_WARN +350 include/linux/rcupdate.h 632ee2001 Paul E. McKenney 2010-02-22 283 4221a9918 Tetsuo Handa 2010-06-26 284 /** f78f5b90c Paul E. McKenney 2015-06-18 285 * RCU_LOCKDEP_WARN - emit lockdep splat if specified condition is met f78f5b90c Paul E. McKenney 2015-06-18 286 * @c: condition to check f78f5b90c Paul E. McKenney 2015-06-18 287 * @s: informative message f78f5b90c Paul E. McKenney 2015-06-18 288 */ f78f5b90c Paul E. McKenney 2015-06-18 289 #define RCU_LOCKDEP_WARN(c, s)
[PATCH net-next 4/4] net: hns3: fix the bug when reuse command description in hclge_add_mac_vlan_tbl
When reusing a command description read from HW, driver should set IN_VLD bit, WR bit and NO_INTR bit. If IN_VLD bit and NO_INTR bit are not set, the command fails and driver prints error message: [ 135.261284] hns3 :7d:00.0: cmdq execute failed for get_mac_vlan_cmd_status,status=2. [ 135.270983] hns3 :7d:00.0: add mac addr failed for cmd_send, ret =-5. This patch fixes the bug. Fixes: 46a3df9 (net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support) Signed-off-by: Lipeng --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index d11a9a5..0b95fbe 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -3600,11 +3600,11 @@ static int hclge_add_mac_vlan_tbl(struct hclge_vport *vport, resp_code, HCLGE_MAC_VLAN_ADD); } else { - mc_desc[0].flag &= cpu_to_le16(~HCLGE_CMD_FLAG_WR); + hclge_cmd_reuse_desc(&mc_desc[0], false); mc_desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); - mc_desc[1].flag &= cpu_to_le16(~HCLGE_CMD_FLAG_WR); + hclge_cmd_reuse_desc(&mc_desc[1], false); mc_desc[1].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); - mc_desc[2].flag &= cpu_to_le16(~HCLGE_CMD_FLAG_WR); + hclge_cmd_reuse_desc(&mc_desc[2], false); mc_desc[2].flag &= cpu_to_le16(~HCLGE_CMD_FLAG_NEXT); memcpy(mc_desc[0].data, req, sizeof(struct hclge_mac_vlan_tbl_entry_cmd)); -- 1.9.1
[PATCH net-next 3/4] net: hns3: fix a bug in hclge_uninit_client_instance
HNS3 driver initialize hdev->roce_client and vport->roce.client in hclge_init_client_instance, and need set hdev->roce_client and vport->roce.client NULL. If do not set them NULL when uninit, it will fail in the scene: insmod hns3.ko, hns-roce.ko, hns-roce-hw-v3.ko successfully, but rmmod hns3.ko after rmmod hns-roce-hw-v2.ko and hns-roce.ko. This patch fixes the issue. Fixes: 46a3df9 (net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support) Signed-off-by: Lipeng --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 2c22d3c..d11a9a5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -4311,13 +4311,19 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, for (i = 0; i < hdev->num_vmdq_vport + 1; i++) { vport = &hdev->vport[i]; - if (hdev->roce_client) + if (hdev->roce_client) { hdev->roce_client->ops->uninit_instance(&vport->roce, 0); + hdev->roce_client = NULL; + vport->roce.client = NULL; + } if (client->type == HNAE3_CLIENT_ROCE) return; - if (client->ops->uninit_instance) + if (client->ops->uninit_instance) { client->ops->uninit_instance(&vport->nic, 0); + hdev->nic_client = NULL; + vport->nic.client = NULL; + } } } -- 1.9.1
[PATCH net-next 2/4] net: hns3: add nic_client check when initialize roce base information
Roce driver works base on HNS3 driver.If insmod Roce driver before NIC driver there is a error because do not check nic_client. This patch adds nic_client check when initialize roce base information. Fixes: 46a3df9 (net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support) Signed-off-by: Lipeng --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 4431241..2c22d3c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -4285,7 +4285,7 @@ static int hclge_init_client_instance(struct hnae3_client *client, vport->roce.client = client; } - if (hdev->roce_client) { + if (hdev->roce_client && hdev->nic_client) { ret = hclge_init_roce_base_info(vport); if (ret) goto err; -- 1.9.1
[PATCH net-next 0/4] net: hns3: fix some bugs for HNS3 driver
This patchset fixes some bugs reported by Hisilicon test team. Lipeng (4): net: hns3: fix the bug of hns3_set_txbd_baseinfo net: hns3: add nic_client check when initialize roce base information net: hns3: fix a bug in hclge_uninit_client_instance net: hns3: fix the bug when reuse command description in hclge_add_mac_vlan_tbl .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 18 -- drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) -- 1.9.1
[PATCH net-next 1/4] net: hns3: fix the bug of hns3_set_txbd_baseinfo
The SC bits of TX BD mean switch control. For this area, value 0 indicates no switch control, the packet is routed according to the forwarding table. Value 1 indicates that the packet is transmitted to the network bypassing the forwarding table. As HNS3 driver need support VF later, VF conmunicate with its own PF need forwarding table. This patch sets SC bits of TX BD 0 and use forwarding table. Fixes: 76ad4f0 (net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC) Signed-off-by: Lipeng --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c index 537f6c3..c6c5b2a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c @@ -716,7 +716,7 @@ static void hns3_set_txbd_baseinfo(u16 *bdtp_fe_sc_vld_ra_ri, int frag_end) HNS3_TXD_BDTYPE_M, 0); hnae_set_bit(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_FE_B, !!frag_end); hnae_set_bit(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_VLD_B, 1); - hnae_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_SC_M, HNS3_TXD_SC_S, 1); + hnae_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_SC_M, HNS3_TXD_SC_S, 0); } static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, -- 1.9.1
[PATCH net-next v2 0/2] bridge: make setlink/dellink notifications more accurate
Hi, Before this set the bridge would generate a notification on vlan add or del even if they didn't actually do any changes, which confuses listeners and is generally not preferred. We could also lose notifications on actual changes if one adds a range of vlans and there's an error in the middle. The problem with just breaking and returning an error is that we could break existing user-space scripts which rely on the vlan delete to clear all existing entries in the specified range and ignore the non-existing errors (typically used to clear the current vlan config). So in order to make the notifications more accurate while keeping backwards compatibility we add a boolean that tracks if anything actually changed during the config calls. The vlan add is more difficult to fix because it always returns 0 even if nothing changed, but we cannot use a specific error because the drivers can return anything and we may mask it, also we'd need to update all places that directly return the add result, thus to signal that a vlan was created or updated and in order not to break overlapping vlan range add we pass down the new boolean that tracks changes to the add functions to check if anything was actually updated. Can't say that I am happy with this change, but currently I don't see any simpler way which doesn't affect user-space. v2: pass changed down to vlan add instead of masking errors Thanks, Nik Nikolay Aleksandrov (2): bridge: netlink: make setlink/dellink notifications more accurate bridge: vlan: signal if anything changed on vlan add net/bridge/br_netlink.c| 51 --- net/bridge/br_netlink_tunnel.c | 14 +--- net/bridge/br_private.h| 6 ++-- net/bridge/br_private_tunnel.h | 3 +- net/bridge/br_vlan.c | 78 ++ 5 files changed, 102 insertions(+), 50 deletions(-) -- 2.1.4
[PATCH net-next v2 1/2] bridge: netlink: make setlink/dellink notifications more accurate
Before this patch we had cases that either sent notifications when there were in fact no changes (e.g. non-existent vlan delete) or didn't send notifications when there were changes (e.g. vlan add range with an error in the middle, port flags change + vlan update error). This patch sends down a boolean to the functions setlink/dellink use and if there is even a single configuration change (port flag, vlan add/del, port state) then we always send a notification. This is all done to keep backwards compatibility with the opportunistic vlan delete, where one could specify a vlan range that has missing vlans inside and still everything in that range will be cleared, this is mostly used to clear the whole vlan config with a single call, i.e. range 1-4094. Signed-off-by: Nikolay Aleksandrov --- net/bridge/br_netlink.c| 44 +- net/bridge/br_netlink_tunnel.c | 14 +- net/bridge/br_private_tunnel.h | 3 ++- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index fb61b6c79235..d0290ede9342 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -506,7 +506,7 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, } static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p, - int cmd, struct bridge_vlan_info *vinfo) + int cmd, struct bridge_vlan_info *vinfo, bool *changed) { int err = 0; @@ -517,21 +517,24 @@ static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p, * per-VLAN entry as well */ err = nbp_vlan_add(p, vinfo->vid, vinfo->flags); - if (err) - break; } else { vinfo->flags |= BRIDGE_VLAN_INFO_BRENTRY; err = br_vlan_add(br, vinfo->vid, vinfo->flags); } + if (!err) + *changed = true; break; case RTM_DELLINK: if (p) { - nbp_vlan_delete(p, vinfo->vid); - if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER) - br_vlan_delete(p->br, vinfo->vid); - } else { - br_vlan_delete(br, vinfo->vid); + if (!nbp_vlan_delete(p, vinfo->vid)) + *changed = true; + + if ((vinfo->flags & BRIDGE_VLAN_INFO_MASTER) && + !br_vlan_delete(p->br, vinfo->vid)) + *changed = true; + } else if (!br_vlan_delete(br, vinfo->vid)) { + *changed = true; } break; } @@ -542,7 +545,8 @@ static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p, static int br_process_vlan_info(struct net_bridge *br, struct net_bridge_port *p, int cmd, struct bridge_vlan_info *vinfo_curr, - struct bridge_vlan_info **vinfo_last) + struct bridge_vlan_info **vinfo_last, + bool *changed) { if (!vinfo_curr->vid || vinfo_curr->vid >= VLAN_VID_MASK) return -EINVAL; @@ -572,7 +576,7 @@ static int br_process_vlan_info(struct net_bridge *br, sizeof(struct bridge_vlan_info)); for (v = (*vinfo_last)->vid; v <= vinfo_curr->vid; v++) { tmp_vinfo.vid = v; - err = br_vlan_info(br, p, cmd, &tmp_vinfo); + err = br_vlan_info(br, p, cmd, &tmp_vinfo, changed); if (err) break; } @@ -581,13 +585,13 @@ static int br_process_vlan_info(struct net_bridge *br, return err; } - return br_vlan_info(br, p, cmd, vinfo_curr); + return br_vlan_info(br, p, cmd, vinfo_curr, changed); } static int br_afspec(struct net_bridge *br, struct net_bridge_port *p, struct nlattr *af_spec, -int cmd) +int cmd, bool *changed) { struct bridge_vlan_info *vinfo_curr = NULL; struct bridge_vlan_info *vinfo_last = NULL; @@ -607,7 +611,8 @@ static int br_afspec(struct net_bridge *br, return err; err = br_process_vlan_tunnel_info(br, p, cmd, &tinfo_curr, - &tinfo_last); + &tinfo_last, + changed); if (err)
[PATCH net-next v2 2/2] bridge: vlan: signal if anything changed on vlan add
Before this patch there was no way to tell if the vlan add operation actually changed anything, thus we would always generate a notification on adds. Let's make the notifications more precise and generate them only if anything changed, so use the new bool parameter to signal that the vlan was updated. We cannot return an error because there are valid use cases that will be broken (e.g. overlapping range add) and also we can't risk masking errors due to calls into drivers for vlan add which can potentially return anything. Signed-off-by: Nikolay Aleksandrov --- v2: pass changed down to vlan add functions instead of using a specific error that needs to be masked net/bridge/br_netlink.c | 9 -- net/bridge/br_private.h | 6 ++-- net/bridge/br_vlan.c| 78 +++-- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index d0290ede9342..e732403669c6 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -508,6 +508,7 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p, int cmd, struct bridge_vlan_info *vinfo, bool *changed) { + bool curr_change; int err = 0; switch (cmd) { @@ -516,12 +517,14 @@ static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p, /* if the MASTER flag is set this will act on the global * per-VLAN entry as well */ - err = nbp_vlan_add(p, vinfo->vid, vinfo->flags); + err = nbp_vlan_add(p, vinfo->vid, vinfo->flags, + &curr_change); } else { vinfo->flags |= BRIDGE_VLAN_INFO_BRENTRY; - err = br_vlan_add(br, vinfo->vid, vinfo->flags); + err = br_vlan_add(br, vinfo->vid, vinfo->flags, + &curr_change); } - if (!err) + if (curr_change) *changed = true; break; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index fa0039f44818..e0eec033d656 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -803,7 +803,8 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, const struct net_bridge_port *port, struct net_bridge_vlan_group *vg, struct sk_buff *skb); -int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags); +int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, + bool *changed); int br_vlan_delete(struct net_bridge *br, u16 vid); void br_vlan_flush(struct net_bridge *br); struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid); @@ -816,7 +817,8 @@ int br_vlan_set_stats(struct net_bridge *br, unsigned long val); int br_vlan_init(struct net_bridge *br); int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val); int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid); -int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); +int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, +bool *changed); int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); void nbp_vlan_flush(struct net_bridge_port *port); int nbp_vlan_init(struct net_bridge_port *port); diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 233a30040c91..fb0a903d19d1 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -32,27 +32,34 @@ static struct net_bridge_vlan *br_vlan_lookup(struct rhashtable *tbl, u16 vid) return rhashtable_lookup_fast(tbl, &vid, br_vlan_rht_params); } -static void __vlan_add_pvid(struct net_bridge_vlan_group *vg, u16 vid) +static bool __vlan_add_pvid(struct net_bridge_vlan_group *vg, u16 vid) { if (vg->pvid == vid) - return; + return false; smp_wmb(); vg->pvid = vid; + + return true; } -static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) +static bool __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) { if (vg->pvid != vid) - return; + return false; smp_wmb(); vg->pvid = 0; + + return true; } -static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags) +/* return true if anything changed, false otherwise */ +static bool __vlan_add_flags(struct net_bridge_vlan *v, u16 flags) { struct net_bridge_vlan_group *vg; + u16 old_flags = v->flags; + bool ret; if (br_vlan_is_master(v)) vg = br_vlan_group(v->br); @@ -60,14 +67,16 @@ static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
[4.14rc6] __tcp_select_window divide by zero.
divide error: [#1] SMP KASAN CPU: 0 PID: 31140 Comm: trinity-c12 Not tainted 4.14.0-rc6-think+ #1 task: 8803c0d08040 task.stack: 8803df548000 RIP: 0010:__tcp_select_window+0x21f/0x400 RSP: 0018:8803df54f418 EFLAGS: 00010246 RAX: RBX: 880458fd3140 RCX: 82120ea5 RDX: RSI: dc00 RDI: 880458fd3a88 RBP: R08: 0001 R09: R10: R11: R12: 00098968 R13: 11007bea9e87 R14: R15: FS: 7f76da1db700() GS:88046ae0() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: CR3: 0003f67cd002 CR4: 001606f0 DR0: 7f76d819f000 DR1: 7f75a29f5000 DR2: DR3: DR6: 0ff0 DR7: 0600 Call Trace: ? tcp_schedule_loss_probe+0x270/0x270 ? lock_acquire+0x12e/0x350 ? tcp_recvmsg+0x124/0x1430 ? lock_release+0x890/0x890 ? do_raw_spin_trylock+0x100/0x100 ? do_raw_spin_trylock+0x40/0x100 tcp_cleanup_rbuf+0x27d/0x2a0 ? tcp_recv_skb+0x180/0x180 ? mark_held_locks+0x70/0xa0 ? __local_bh_enable_ip+0x60/0x90 tcp_recvmsg+0x7a9/0x1430 ? tcp_recv_timestamp+0x250/0x250 ? __free_insn_slot+0x390/0x390 ? rcu_is_watching+0x88/0xd0 ? entry_SYSCALL64_slow_path+0x25/0x25 ? is_bpf_text_address+0x86/0xf0 ? kernel_text_address+0xec/0x100 ? __kernel_text_address+0xe/0x30 ? unwind_get_return_address+0x2f/0x50 ? __save_stack_trace+0x92/0x100 ? memcmp+0x45/0x70 ? match_held_lock+0x93/0x410 ? save_trace+0x1c0/0x1c0 ? save_stack+0x89/0xb0 ? save_stack+0x32/0xb0 ? kasan_kmalloc+0xa0/0xd0 ? native_sched_clock+0xf9/0x1a0 ? rw_copy_check_uvector+0x15e/0x180 inet_recvmsg+0x10b/0x360 ? inet_create+0x770/0x770 ? sched_clock_cpu+0x14/0xf0 ? sched_clock_cpu+0x14/0xf0 sock_read_iter+0x19d/0x240 ? sock_recvmsg+0x60/0x60 do_iter_readv_writev+0x2e4/0x320 ? vfs_dedupe_file_range+0x3e0/0x3e0 do_iter_read+0x149/0x280 vfs_readv+0x107/0x180 ? compat_rw_copy_check_uvector+0x1d0/0x1d0 ? fget_raw+0x10/0x10 ? __lock_is_held+0x2e/0xd0 ? do_preadv+0xf0/0xf0 ? __fdget_pos+0x82/0x110 ? __fdget_raw+0x10/0x10 ? do_readv+0xc0/0x1b0 do_readv+0xc0/0x1b0 ? vfs_readv+0x180/0x180 ? mark_held_locks+0x1b/0xa0 ? do_syscall_64+0xae/0x400 ? do_preadv+0xf0/0xf0 do_syscall_64+0x182/0x400 ? syscall_return_slowpath+0x270/0x270 ? rcu_read_lock_sched_held+0x90/0xa0 ? __context_tracking_exit.part.4+0x223/0x290 ? mark_held_locks+0x1b/0xa0 ? return_from_SYSCALL_64+0x2d/0x7a ? trace_hardirqs_on_caller+0x17a/0x250 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL64_slow_path+0x25/0x25 RIP: 0033:0x7f76d9b05219 RSP: 002b:7ffd41fd30d8 EFLAGS: 0246 ORIG_RAX: 0013 RAX: ffda RBX: 0013 RCX: 7f76d9b05219 RDX: 0016 RSI: 5611ca731c70 RDI: 0179 RBP: 7ffd41fd3180 R08: 00a07395 R09: 000a10d65a68 R10: 0001 R11: 0246 R12: 0002 R13: 7f76da180058 R14: 7f76da1db698 R15: 7f76da18 Code: 41 5e 41 5f c3 48 8d bb 48 09 00 00 e8 4b 2b 30 ff 8b 83 48 09 00 00 89 ea 44 29 f2 39 c2 7d 08 39 c5 0f 8d 86 01 00 00 89 e8 99 <41> f7 fe 89 e8 29 d0 eb 8c 41 f7 df 48 89 c7 44 89 f9 d3 fd e8 RIP: __tcp_select_window+0x21f/0x400 RSP: 8803df54f418 window = rounddown(free_space, mss); 45ec: 89 e8 mov%ebp,%eax 45ee: 99 cltd 45ef: 41 f7 feidiv %r14d 45f2: 89 e8 mov%ebp,%eax 45f4: 29 d0 sub%edx,%eax 45f6: eb 8c jmp4584 <__tcp_select_window+0x1b4> 45f8: 41 f7 dfneg%r15d