* [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
[not found] <20221027150525.753064657@goodmis.org>
@ 2022-10-27 15:05 ` Steven Rostedt
2022-10-27 19:55 ` Steven Rostedt
2022-10-27 15:05 ` [RFC][PATCH v2 20/31] timers: usb: " Steven Rostedt
[not found] ` <20221028021815.3130-1-hdanton@sina.com>
2 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 15:05 UTC (permalink / raw)
To: linux-kernel
Cc: Linus Torvalds, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
Before a timer is freed, del_timer_shutdown() must be called.
Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home/
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Mirko Lindner <mlindner@marvell.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Martin KaFai Lau <martin.lau@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: Pavel Begunkov <asml.silence@gmail.com>
Cc: Menglong Dong <imagedong@tencent.com>
Cc: linux-usb@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Cc: bridge@lists.linux-foundation.org
Cc: netfilter-devel@vger.kernel.org
Cc: coreteam@netfilter.org
Cc: lvs-devel@vger.kernel.org
Cc: linux-afs@lists.infradead.org
Cc: linux-nfs@vger.kernel.org
Cc: tipc-discussion@lists.sourceforge.net
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +++---
drivers/net/ethernet/marvell/sky2.c | 2 +-
drivers/net/ethernet/sun/sunvnet.c | 2 +-
drivers/net/usb/sierra_net.c | 2 +-
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 2 +-
drivers/net/wireless/intersil/hostap/hostap_ap.c | 2 +-
drivers/net/wireless/marvell/mwifiex/main.c | 2 +-
drivers/net/wireless/microchip/wilc1000/hif.c | 8 ++++----
net/802/garp.c | 2 +-
net/802/mrp.c | 2 +-
net/bridge/br_multicast.c | 6 +++---
net/bridge/br_multicast_eht.c | 4 ++--
net/core/gen_estimator.c | 2 +-
net/core/sock.c | 2 +-
net/ipv4/inet_timewait_sock.c | 2 +-
net/ipv4/ipmr.c | 2 +-
net/ipv6/ip6mr.c | 2 +-
net/mac80211/mesh_pathtbl.c | 2 +-
net/netfilter/ipset/ip_set_list_set.c | 2 +-
net/netfilter/ipvs/ip_vs_lblc.c | 2 +-
net/netfilter/ipvs/ip_vs_lblcr.c | 2 +-
net/netfilter/xt_LED.c | 2 +-
net/rxrpc/conn_object.c | 2 +-
net/sched/cls_flow.c | 2 +-
net/sunrpc/svc.c | 2 +-
net/tipc/discover.c | 2 +-
net/tipc/monitor.c | 2 +-
27 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 2c07fa8ecfc8..81e9f232ca69 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -15528,7 +15528,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw)
err_switch_setup:
i40e_reset_interrupt_capability(pf);
- del_timer_sync(&pf->service_timer);
+ del_timer_shutdown(&pf->service_timer);
i40e_shutdown_adminq(hw);
iounmap(hw->hw_addr);
pci_disable_pcie_error_reporting(pf->pdev);
@@ -16147,7 +16147,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
kfree(pf->vsi);
err_switch_setup:
i40e_reset_interrupt_capability(pf);
- del_timer_sync(&pf->service_timer);
+ del_timer_shutdown(&pf->service_timer);
err_mac_addr:
err_configure_lan_hmc:
(void)i40e_shutdown_lan_hmc(hw);
@@ -16209,7 +16209,7 @@ static void i40e_remove(struct pci_dev *pdev)
set_bit(__I40E_SUSPENDED, pf->state);
set_bit(__I40E_DOWN, pf->state);
if (pf->service_timer.function)
- del_timer_sync(&pf->service_timer);
+ del_timer_shutdown(&pf->service_timer);
if (pf->service_task.func)
cancel_work_sync(&pf->service_task);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index ab33ba1c3023..9d8a9ae64681 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -5013,7 +5013,7 @@ static void sky2_remove(struct pci_dev *pdev)
if (!hw)
return;
- del_timer_sync(&hw->watchdog_timer);
+ del_timer_shutdown(&hw->watchdog_timer);
cancel_work_sync(&hw->restart_work);
for (i = hw->ports-1; i >= 0; --i)
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index acda6cbd0238..f008812356ef 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -524,7 +524,7 @@ static void vnet_port_remove(struct vio_dev *vdev)
hlist_del_rcu(&port->hash);
synchronize_rcu();
- del_timer_sync(&port->clean_timer);
+ del_timer_shutdown(&port->clean_timer);
sunvnet_port_rm_txq_common(port);
netif_napi_del(&port->napi);
sunvnet_port_free_tx_bufs_common(port);
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index b3ae949e6f1c..75d4956fc1e6 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -759,7 +759,7 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
dev_dbg(&dev->udev->dev, "%s", __func__);
/* kill the timer and work */
- del_timer_sync(&priv->sync_timer);
+ del_timer_shutdown(&priv->sync_timer);
cancel_work_sync(&priv->sierra_net_kevent);
/* tell modem we are going away */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 3237d4b528b5..dced4d0384c7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -371,7 +371,7 @@ void iwl_dbg_tlv_del_timers(struct iwl_trans *trans)
struct iwl_dbg_tlv_timer_node *node, *tmp;
list_for_each_entry_safe(node, tmp, timer_list, list) {
- del_timer_sync(&node->timer);
+ del_timer_shutdown(&node->timer);
list_del(&node->list);
kfree(node);
}
diff --git a/drivers/net/wireless/intersil/hostap/hostap_ap.c b/drivers/net/wireless/intersil/hostap/hostap_ap.c
index 462ccc7d7d1a..34236d793b80 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_ap.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_ap.c
@@ -135,7 +135,7 @@ static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
if (!sta->ap)
kfree(sta->u.sta.challenge);
- del_timer_sync(&sta->timer);
+ del_timer_shutdown(&sta->timer);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
kfree(sta);
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index da2e6557e684..8fd4d603fe37 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -123,7 +123,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
if (adapter->if_ops.cleanup_if)
adapter->if_ops.cleanup_if(adapter);
- del_timer_sync(&adapter->cmd_timer);
+ del_timer_shutdown(&adapter->cmd_timer);
/* Free private structures */
for (i = 0; i < adapter->priv_num; i++) {
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
index eb1d1ba3a443..7a96f9828c97 100644
--- a/drivers/net/wireless/microchip/wilc1000/hif.c
+++ b/drivers/net/wireless/microchip/wilc1000/hif.c
@@ -1520,10 +1520,10 @@ int wilc_deinit(struct wilc_vif *vif)
mutex_lock(&vif->wilc->deinit_lock);
- del_timer_sync(&hif_drv->scan_timer);
- del_timer_sync(&hif_drv->connect_timer);
- del_timer_sync(&vif->periodic_rssi);
- del_timer_sync(&hif_drv->remain_on_ch_timer);
+ del_timer_shutdown(&hif_drv->scan_timer);
+ del_timer_shutdown(&hif_drv->connect_timer);
+ del_timer_shutdown(&vif->periodic_rssi);
+ del_timer_shutdown(&hif_drv->remain_on_ch_timer);
if (hif_drv->usr_scan_req.scan_result) {
hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
diff --git a/net/802/garp.c b/net/802/garp.c
index fc9eb02a912f..610753f269ca 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -618,7 +618,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
/* Delete timer and generate a final TRANSMIT_PDU event to flush out
* all pending messages before the applicant is gone. */
- del_timer_sync(&app->join_timer);
+ del_timer_shutdown(&app->join_timer);
spin_lock_bh(&app->lock);
garp_gid_event(app, GARP_EVENT_TRANSMIT_PDU);
diff --git a/net/802/mrp.c b/net/802/mrp.c
index 155f74d8b14f..72d4680ce170 100644
--- a/net/802/mrp.c
+++ b/net/802/mrp.c
@@ -904,7 +904,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
* all pending messages before the applicant is gone.
*/
del_timer_sync(&app->join_timer);
- del_timer_sync(&app->periodic_timer);
+ del_timer_shutdown(&app->periodic_timer);
spin_lock_bh(&app->lock);
mrp_mad_event(app, MRP_EVENT_TX);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index db4f2641d1cd..0724c45049e4 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -605,7 +605,7 @@ static void br_multicast_destroy_mdb_entry(struct net_bridge_mcast_gc *gc)
WARN_ON(!hlist_unhashed(&mp->mdb_node));
WARN_ON(mp->ports);
- del_timer_sync(&mp->timer);
+ del_timer_shutdown(&mp->timer);
kfree_rcu(mp, rcu);
}
@@ -646,7 +646,7 @@ static void br_multicast_destroy_group_src(struct net_bridge_mcast_gc *gc)
src = container_of(gc, struct net_bridge_group_src, mcast_gc);
WARN_ON(!hlist_unhashed(&src->node));
- del_timer_sync(&src->timer);
+ del_timer_shutdown(&src->timer);
kfree_rcu(src, rcu);
}
@@ -671,7 +671,7 @@ static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc)
WARN_ON(!hlist_empty(&pg->src_list));
del_timer_sync(&pg->rexmit_timer);
- del_timer_sync(&pg->timer);
+ del_timer_shutdown(&pg->timer);
kfree_rcu(pg, rcu);
}
diff --git a/net/bridge/br_multicast_eht.c b/net/bridge/br_multicast_eht.c
index f91c071d1608..78dcfba2b16c 100644
--- a/net/bridge/br_multicast_eht.c
+++ b/net/bridge/br_multicast_eht.c
@@ -142,7 +142,7 @@ static void br_multicast_destroy_eht_set_entry(struct net_bridge_mcast_gc *gc)
set_h = container_of(gc, struct net_bridge_group_eht_set_entry, mcast_gc);
WARN_ON(!RB_EMPTY_NODE(&set_h->rb_node));
- del_timer_sync(&set_h->timer);
+ del_timer_shutdown(&set_h->timer);
kfree(set_h);
}
@@ -154,7 +154,7 @@ static void br_multicast_destroy_eht_set(struct net_bridge_mcast_gc *gc)
WARN_ON(!RB_EMPTY_NODE(&eht_set->rb_node));
WARN_ON(!RB_EMPTY_ROOT(&eht_set->entry_tree));
- del_timer_sync(&eht_set->timer);
+ del_timer_shutdown(&eht_set->timer);
kfree(eht_set);
}
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 4fcbdd71c59f..834287d0675e 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -208,7 +208,7 @@ void gen_kill_estimator(struct net_rate_estimator __rcu **rate_est)
est = xchg((__force struct net_rate_estimator **)rate_est, NULL);
if (est) {
- del_timer_sync(&est->timer);
+ del_timer_shutdown(&est->timer);
kfree_rcu(est, rcu);
}
}
diff --git a/net/core/sock.c b/net/core/sock.c
index a3ba0358c77c..10cc84379d75 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3352,7 +3352,7 @@ EXPORT_SYMBOL(sk_stop_timer);
void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
{
- if (del_timer_sync(timer))
+ if (del_timer_shutdown(timer))
__sock_put(sk);
}
EXPORT_SYMBOL(sk_stop_timer_sync);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 66fc940f9521..549a4c1990ea 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -208,7 +208,7 @@ EXPORT_SYMBOL_GPL(inet_twsk_alloc);
*/
void inet_twsk_deschedule_put(struct inet_timewait_sock *tw)
{
- if (del_timer_sync(&tw->tw_timer))
+ if (del_timer_shutdown(&tw->tw_timer))
inet_twsk_kill(tw);
inet_twsk_put(tw);
}
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index e04544ac4b45..459a80325247 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -412,7 +412,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
static void ipmr_free_table(struct mr_table *mrt)
{
- del_timer_sync(&mrt->ipmr_expire_timer);
+ del_timer_shutdown(&mrt->ipmr_expire_timer);
mroute_clean_tables(mrt, MRT_FLUSH_VIFS | MRT_FLUSH_VIFS_STATIC |
MRT_FLUSH_MFC | MRT_FLUSH_MFC_STATIC);
rhltable_destroy(&mrt->mfc_hash);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index facdc78a43e5..9bd993046ebe 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -392,7 +392,7 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
static void ip6mr_free_table(struct mr_table *mrt)
{
- del_timer_sync(&mrt->ipmr_expire_timer);
+ del_timer_shutdown(&mrt->ipmr_expire_timer);
mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MIFS_STATIC |
MRT6_FLUSH_MFC | MRT6_FLUSH_MFC_STATIC);
rhltable_destroy(&mrt->mfc_hash);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index acc1c299f1ae..d4c7c67a4dee 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -512,7 +512,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl,
mpath->flags |= MESH_PATH_RESOLVING | MESH_PATH_DELETED;
mesh_gate_del(tbl, mpath);
spin_unlock_bh(&mpath->state_lock);
- del_timer_sync(&mpath->timer);
+ del_timer_shutdown(&mpath->timer);
atomic_dec(&sdata->u.mesh.mpaths);
atomic_dec(&tbl->entries);
mesh_path_flush_pending(mpath);
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 5a67f7966574..6a8b0e80385b 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -427,7 +427,7 @@ list_set_destroy(struct ip_set *set)
struct set_elem *e, *n;
if (SET_WITH_TIMEOUT(set))
- del_timer_sync(&map->gc);
+ del_timer_shutdown(&map->gc);
list_for_each_entry_safe(e, n, &map->members, list) {
list_del(&e->list);
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 7ac7473e3804..1f08ba927d0e 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -384,7 +384,7 @@ static void ip_vs_lblc_done_svc(struct ip_vs_service *svc)
struct ip_vs_lblc_table *tbl = svc->sched_data;
/* remove periodic timer */
- del_timer_sync(&tbl->periodic_timer);
+ del_timer_shutdown(&tbl->periodic_timer);
/* got to clean up table entries here */
ip_vs_lblc_flush(svc);
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 77c323c36a88..f939a00826d6 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -547,7 +547,7 @@ static void ip_vs_lblcr_done_svc(struct ip_vs_service *svc)
struct ip_vs_lblcr_table *tbl = svc->sched_data;
/* remove periodic timer */
- del_timer_sync(&tbl->periodic_timer);
+ del_timer_shutdown(&tbl->periodic_timer);
/* got to clean up table entries here */
ip_vs_lblcr_flush(svc);
diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c
index 0371c387b0d1..0093fa1d07c6 100644
--- a/net/netfilter/xt_LED.c
+++ b/net/netfilter/xt_LED.c
@@ -166,7 +166,7 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par)
list_del(&ledinternal->list);
- del_timer_sync(&ledinternal->timer);
+ del_timer_shutdown(&ledinternal->timer);
led_trigger_unregister(&ledinternal->netfilter_led_trigger);
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index 22089e37e97f..3f353f1f38ee 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -358,7 +358,7 @@ static void rxrpc_destroy_connection(struct rcu_head *rcu)
_net("DESTROY CONN %d", conn->debug_id);
- del_timer_sync(&conn->timer);
+ del_timer_shutdown(&conn->timer);
rxrpc_purge_queue(&conn->rx_queue);
conn->security->clear(conn);
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 014cd3de7b5d..b23fbd2d4b5a 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -367,7 +367,7 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
static void __flow_destroy_filter(struct flow_filter *f)
{
- del_timer_sync(&f->perturb_timer);
+ del_timer_shutdown(&f->perturb_timer);
tcf_exts_destroy(&f->exts);
tcf_em_tree_destroy(&f->ematches);
tcf_exts_put_net(&f->exts);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 149171774bc6..b07bc9f9b3bd 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -567,7 +567,7 @@ svc_destroy(struct kref *ref)
struct svc_serv *serv = container_of(ref, struct svc_serv, sv_refcnt);
dprintk("svc: svc_destroy(%s)\n", serv->sv_program->pg_name);
- del_timer_sync(&serv->sv_temptimer);
+ del_timer_shutdown(&serv->sv_temptimer);
/*
* The last user is gone and thus all sockets have to be destroyed to
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index da69e1abf68f..09d69670506e 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -385,7 +385,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b,
*/
void tipc_disc_delete(struct tipc_discoverer *d)
{
- del_timer_sync(&d->timer);
+ del_timer_shutdown(&d->timer);
kfree_skb(d->skb);
kfree(d);
}
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index 9618e4429f0f..cedc4a468315 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -700,7 +700,7 @@ void tipc_mon_delete(struct net *net, int bearer_id)
}
mon->self = NULL;
write_unlock_bh(&mon->lock);
- del_timer_sync(&mon->timer);
+ del_timer_shutdown(&mon->timer);
kfree(self->domain);
kfree(self);
kfree(mon);
--
2.35.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
[not found] <20221027150525.753064657@goodmis.org>
2022-10-27 15:05 ` [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer Steven Rostedt
@ 2022-10-27 15:05 ` Steven Rostedt
2022-10-27 20:38 ` Alan Stern
2022-10-28 5:23 ` Guenter Roeck
[not found] ` <20221028021815.3130-1-hdanton@sina.com>
2 siblings, 2 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 15:05 UTC (permalink / raw)
To: linux-kernel
Cc: Linus Torvalds, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
Before a timer is freed, del_timer_shutdown() must be called.
Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home/
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Felipe Balbi <balbi@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Mathias Nyman <mathias.nyman@linux.intel.com>
Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
Cc: Matthias Kaehlcke <mka@chromium.org>
Cc: Michael Grzeschik <m.grzeschik@pengutronix.de>
Cc: Bhuvanesh Surachari <Bhuvanesh_Surachari@mentor.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: linux-usb@vger.kernel.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
drivers/usb/core/hub.c | 3 +++
drivers/usb/gadget/udc/m66592-udc.c | 2 +-
drivers/usb/serial/garmin_gps.c | 2 +-
drivers/usb/serial/mos7840.c | 2 +-
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bbab424b0d55..397f263ab7da 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1261,6 +1261,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
/* Don't do a long sleep inside a workqueue routine */
if (type == HUB_INIT2) {
+ /* Timers must be shutdown before they are re-initialized */
+ if (hub->init_work.work.func)
+ del_timer_shutdown(&hub->init_work.timer);
INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
queue_delayed_work(system_power_efficient_wq,
&hub->init_work,
diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c
index 931e6362a13d..a6e2f8358adf 100644
--- a/drivers/usb/gadget/udc/m66592-udc.c
+++ b/drivers/usb/gadget/udc/m66592-udc.c
@@ -1519,7 +1519,7 @@ static int m66592_remove(struct platform_device *pdev)
usb_del_gadget_udc(&m66592->gadget);
- del_timer_sync(&m66592->timer);
+ del_timer_shutdown(&m66592->timer);
iounmap(m66592->reg);
free_irq(platform_get_irq(pdev, 0), m66592);
m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index f1a8d8343623..2a53f26468bd 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1405,7 +1405,7 @@ static void garmin_port_remove(struct usb_serial_port *port)
usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
usb_kill_urb(port->interrupt_in_urb);
- del_timer_sync(&garmin_data_p->timer);
+ del_timer_shutdown(&garmin_data_p->timer);
kfree(garmin_data_p);
}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 6b12bb4648b8..a90a706d27de 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -1726,7 +1726,7 @@ static void mos7840_port_remove(struct usb_serial_port *port)
mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
del_timer_sync(&mos7840_port->led_timer1);
- del_timer_sync(&mos7840_port->led_timer2);
+ del_timer_shutdown(&mos7840_port->led_timer2);
usb_kill_urb(mos7840_port->led_urb);
usb_free_urb(mos7840_port->led_urb);
--
2.35.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 15:05 ` [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer Steven Rostedt
@ 2022-10-27 19:55 ` Steven Rostedt
2022-10-27 20:15 ` Linus Torvalds
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 19:55 UTC (permalink / raw)
To: linux-kernel
Cc: Linus Torvalds, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 27 Oct 2022 12:38:16 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
> On 10/27/22 12:27, Steven Rostedt wrote:
> > On Thu, 27 Oct 2022 15:20:58 -0400
> > Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> >>> (many more of those)
> >>> ...
> >>> [ 16.329989] timer_fixup_free+0x40/0x54
> >>
> >> Ah, I see the issue here. Looks like the timer_fixup_free() is calling
> >> itself and crashing.
> >>
> >> Let me take a look into that. I didn't touch the fixup code, and there
> >> could be an assumption there that it's behaving with the old approach.
> >
> > Can you add this and see if it makes this issue go away?
> >
>
> Yes, that fixes the crash. However, it still reports
>
> [ 12.235054] ------------[ cut here ]------------
> [ 12.235240] ODEBUG: free active (active state 0) object type: timer_list hint: tcp_write_timer+0x0/0x190
> [ 12.237331] WARNING: CPU: 0 PID: 310 at lib/debugobjects.c:502 debug_print_object+0xb8/0x100
> ...
> [ 12.255251] Call trace:
> [ 12.255305] debug_print_object+0xb8/0x100
> [ 12.255385] __debug_check_no_obj_freed+0x1d0/0x25c
> [ 12.255474] debug_check_no_obj_freed+0x20/0x90
> [ 12.255555] slab_free_freelist_hook.constprop.0+0xac/0x1b0
> [ 12.255650] kmem_cache_free+0x1ac/0x500
> [ 12.255728] __sk_destruct+0x140/0x2a0
> [ 12.255805] sk_destruct+0x54/0x64
> [ 12.255877] __sk_free+0x74/0x120
> [ 12.255944] sk_free+0x64/0x8c
> [ 12.256009] tcp_close+0x94/0xc0
> [ 12.256076] inet_release+0x50/0xb0
> [ 12.256145] __sock_release+0x44/0xbc
> [ 12.256219] sock_close+0x18/0x30
> [ 12.256292] __fput+0x84/0x270
> [ 12.256361] ____fput+0x10/0x20
> [ 12.256426] task_work_run+0x88/0xf0
> [ 12.256499] do_exit+0x334/0xafc
> [ 12.256566] do_group_exit+0x34/0x90
> [ 12.256634] __arm64_sys_exit_group+0x18/0x20
> [ 12.256713] invoke_syscall+0x48/0x114
> [ 12.256789] el0_svc_common.constprop.0+0x60/0x11c
> [ 12.256874] do_el0_svc+0x30/0xd0
> [ 12.256943] el0_svc+0x48/0xc0
> [ 12.257008] el0t_64_sync_handler+0xbc/0x13c
> [ 12.257086] el0t_64_sync+0x18c/0x190
>
> Is that a real problem or a false positive ? I didn't see that
> without your patch series (which of course might be the whole point
> of the series).
>
I think this is indeed an issue, and I'm replying to the net patch as it
has the necessary folks Cc'd.
The ipv4 tcp code has:
void tcp_init_xmit_timers(struct sock *sk)
{
inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer,
&tcp_keepalive_timer);
And from the above back trace:
tcp_close() where I'm assuming that tcp_disconnect() or tcp_done() was
called that both calls:
tcp_clear_xmit_timers(sk);
That calls:
inet_csk_clear_xmit_timers(sk);
That has:
void inet_csk_clear_xmit_timers(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
icsk->icsk_pending = icsk->icsk_ack.pending = 0;
sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
sk_stop_timer(sk, &icsk->icsk_delack_timer);
sk_stop_timer(sk, &sk->sk_timer);
}
Where:
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
if (del_timer(timer))
__sock_put(sk);
}
Hence, this is a case where we have timers that have been disabled with
only del_timer() before the timers are freed.
I think we need to update this code to squeeze in a del_timer_shutdown() to
make sure that the timers are never restarted.
There is a sk_stop_timer_sync() that I changed to use del_timer_shutdown()
but that's only used in one file: net/mptcp/pm_netlink.c
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 19:55 ` Steven Rostedt
@ 2022-10-27 20:15 ` Linus Torvalds
2022-10-27 20:34 ` Steven Rostedt
0 siblings, 1 reply; 37+ messages in thread
From: Linus Torvalds @ 2022-10-27 20:15 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, Oct 27, 2022 at 12:55 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> I think we need to update this code to squeeze in a del_timer_shutdown() to
> make sure that the timers are never restarted.
So the reason the networking code does this is that it can't just do
the old 'sync()' thing, the timers are deleted in contexts where that
isn't valid.
Which is also afaik why the networking code does that whole "timer
implies a refcount to the socket" and then does the
if (del_timer(timer))
sock_put()
thing (ie if the del_timer failed - possibly because it was already
running - you leave the refcount alone).
So the networking code cannot do the del_timer_shutdown() for the same
reason it cannot do the del_timer_sync(): it can't afford to wait for
the timer to stop running.
I suspect it needs something like a new "del_timer_shutdown_async()"
that isn't synchronous, but does that
- acts as del_timer in that it doesn't wait, and returns a success if
it could just remove the pending case
- does that "mark timer for shutdown" in that success case
or something similar.
But the networking people will know better.
Linus
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 20:15 ` Linus Torvalds
@ 2022-10-27 20:34 ` Steven Rostedt
2022-10-27 20:48 ` Linus Torvalds
2022-10-27 21:07 ` Steven Rostedt
0 siblings, 2 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 20:34 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 27 Oct 2022 13:15:23 -0700
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Thu, Oct 27, 2022 at 12:55 PM Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > I think we need to update this code to squeeze in a del_timer_shutdown() to
> > make sure that the timers are never restarted.
>
> So the reason the networking code does this is that it can't just do
> the old 'sync()' thing, the timers are deleted in contexts where that
> isn't valid.
>
> Which is also afaik why the networking code does that whole "timer
> implies a refcount to the socket" and then does the
>
> if (del_timer(timer))
> sock_put()
>
> thing (ie if the del_timer failed - possibly because it was already
> running - you leave the refcount alone).
OK, so the above is assuming that the timer is always active, and
del_timer() returns if it successfully removed it (where it can call
sock_put()), but if del_timer() returns 0, that means the timer is
currently running (or about to be), so it doesn't call sock_put().
>
> So the networking code cannot do the del_timer_shutdown() for the same
> reason it cannot do the del_timer_sync(): it can't afford to wait for
> the timer to stop running.
>
> I suspect it needs something like a new "del_timer_shutdown_async()"
> that isn't synchronous, but does that
>
> - acts as del_timer in that it doesn't wait, and returns a success if
> it could just remove the pending case
>
> - does that "mark timer for shutdown" in that success case
>
> or something similar.
>
What about del_timer_try_shutdown(), that if it removes the timer, it sets
the function to NULL (making it equivalent to a successful shutdown),
otherwise it does nothing. Allowing the the timer to be rearmed.
I think this would work in this case.
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-27 15:05 ` [RFC][PATCH v2 20/31] timers: usb: " Steven Rostedt
@ 2022-10-27 20:38 ` Alan Stern
2022-10-27 20:42 ` Steven Rostedt
2022-10-28 5:23 ` Guenter Roeck
1 sibling, 1 reply; 37+ messages in thread
From: Alan Stern @ 2022-10-27 20:38 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Guenter Roeck, Greg Kroah-Hartman, Felipe Balbi, Johan Hovold,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb
On Thu, Oct 27, 2022 at 11:05:45AM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
>
> Before a timer is freed, del_timer_shutdown() must be called.
Is this supposed to be true for all timers? Because the USB subsystem
contains an awful lot more timers than just the two you touched in this
patch.
Alan Stern
> Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home/
>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Felipe Balbi <balbi@kernel.org>
> Cc: Johan Hovold <johan@kernel.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Mathias Nyman <mathias.nyman@linux.intel.com>
> Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Cc: Matthias Kaehlcke <mka@chromium.org>
> Cc: Michael Grzeschik <m.grzeschik@pengutronix.de>
> Cc: Bhuvanesh Surachari <Bhuvanesh_Surachari@mentor.com>
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> ---
> drivers/usb/core/hub.c | 3 +++
> drivers/usb/gadget/udc/m66592-udc.c | 2 +-
> drivers/usb/serial/garmin_gps.c | 2 +-
> drivers/usb/serial/mos7840.c | 2 +-
> 4 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index bbab424b0d55..397f263ab7da 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -1261,6 +1261,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
>
> /* Don't do a long sleep inside a workqueue routine */
> if (type == HUB_INIT2) {
> + /* Timers must be shutdown before they are re-initialized */
> + if (hub->init_work.work.func)
> + del_timer_shutdown(&hub->init_work.timer);
> INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
> queue_delayed_work(system_power_efficient_wq,
> &hub->init_work,
> diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c
> index 931e6362a13d..a6e2f8358adf 100644
> --- a/drivers/usb/gadget/udc/m66592-udc.c
> +++ b/drivers/usb/gadget/udc/m66592-udc.c
> @@ -1519,7 +1519,7 @@ static int m66592_remove(struct platform_device *pdev)
>
> usb_del_gadget_udc(&m66592->gadget);
>
> - del_timer_sync(&m66592->timer);
> + del_timer_shutdown(&m66592->timer);
> iounmap(m66592->reg);
> free_irq(platform_get_irq(pdev, 0), m66592);
> m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-27 20:38 ` Alan Stern
@ 2022-10-27 20:42 ` Steven Rostedt
2022-10-27 21:22 ` Steven Rostedt
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 20:42 UTC (permalink / raw)
To: Alan Stern
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Guenter Roeck, Greg Kroah-Hartman, Felipe Balbi, Johan Hovold,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb
On Thu, 27 Oct 2022 16:38:19 -0400
Alan Stern <stern@rowland.harvard.edu> wrote:
> On Thu, Oct 27, 2022 at 11:05:45AM -0400, Steven Rostedt wrote:
> > From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
> >
> > Before a timer is freed, del_timer_shutdown() must be called.
>
> Is this supposed to be true for all timers? Because the USB subsystem
> contains an awful lot more timers than just the two you touched in this
> patch.
Yes, and this does mean that we are going to have to painstakingly find and
fix ever one of them. This is why the last patch updates
DEBUG_OBJECTS_TIMERS to detect cases where I miss.
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 20:34 ` Steven Rostedt
@ 2022-10-27 20:48 ` Linus Torvalds
2022-10-27 21:07 ` Steven Rostedt
2022-10-27 21:07 ` Steven Rostedt
1 sibling, 1 reply; 37+ messages in thread
From: Linus Torvalds @ 2022-10-27 20:48 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, Oct 27, 2022 at 1:34 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> What about del_timer_try_shutdown(), that if it removes the timer, it sets
> the function to NULL (making it equivalent to a successful shutdown),
> otherwise it does nothing. Allowing the the timer to be rearmed.
Sounds sane to me and should work, but as mentioned, I think the
networking people need to say "yeah" too.
And maybe that function can also disallow any future re-arming even
for the case where the timer couldn't be actively removed.
So any *currently* active timer wouldn't be waited for (either because
locking may make that a deadlock situation, or simply due to
performance issues), but at least it would guarantee that no new timer
activations can happen.
Because I do like the whole notion of "timer has been shutdown and
cannot be used as a timer any more without re-initializing it" being a
real state - even for a timer that may be "currently in flight".
So this all sounds very worthwhile to me, but I'm not surprised that
we have code that then knows about all the subtleties of "del_timer()
might still have a running timer" and actually take advantage of it
(where "advantage" is likely more of a "deal with the complexities"
rather than anything really positive ;)
And those existing subtle users might want particular semantics to at
least make said complexities easier.
Linus
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 20:48 ` Linus Torvalds
@ 2022-10-27 21:07 ` Steven Rostedt
2022-10-27 21:15 ` Steven Rostedt
2022-10-27 22:35 ` Steven Rostedt
0 siblings, 2 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 21:07 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 27 Oct 2022 13:48:54 -0700
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Thu, Oct 27, 2022 at 1:34 PM Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > What about del_timer_try_shutdown(), that if it removes the timer, it sets
> > the function to NULL (making it equivalent to a successful shutdown),
> > otherwise it does nothing. Allowing the the timer to be rearmed.
>
> Sounds sane to me and should work, but as mentioned, I think the
> networking people need to say "yeah" too.
>
> And maybe that function can also disallow any future re-arming even
> for the case where the timer couldn't be actively removed.
Well, I think this current use case will break if we prevent the timer from
being rearmed or run again if it's not found. But as you said, the
networking folks need to confirm or deny it.
The fact that it does the sock_put() when it removes the timer makes me
think that it can be called again, and we shouldn't prevent that from
happening.
The debug code will let us know too, as it only "frees" it for freeing if
it deactivated the timer and shut it down.
>
> So any *currently* active timer wouldn't be waited for (either because
> locking may make that a deadlock situation, or simply due to
> performance issues), but at least it would guarantee that no new timer
> activations can happen.
>
> Because I do like the whole notion of "timer has been shutdown and
> cannot be used as a timer any more without re-initializing it" being a
> real state - even for a timer that may be "currently in flight".
>
> So this all sounds very worthwhile to me, but I'm not surprised that
> we have code that then knows about all the subtleties of "del_timer()
> might still have a running timer" and actually take advantage of it
> (where "advantage" is likely more of a "deal with the complexities"
> rather than anything really positive ;)
Good to hear. This has been a thorn in our side as we keep hitting these
crashes in the timer code that look like a timer was freed before it
triggered.
>
> And those existing subtle users might want particular semantics to at
> least make said complexities easier.
>
Yeah, as someone told me recently, "If you let them play long enough without
setting out the rules, they will take advantage of everything and it will be
extremely hard to get them back in order".
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 20:34 ` Steven Rostedt
2022-10-27 20:48 ` Linus Torvalds
@ 2022-10-27 21:07 ` Steven Rostedt
2022-10-28 15:16 ` Guenter Roeck
1 sibling, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 21:07 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 27 Oct 2022 16:34:53 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> What about del_timer_try_shutdown(), that if it removes the timer, it sets
> the function to NULL (making it equivalent to a successful shutdown),
> otherwise it does nothing. Allowing the the timer to be rearmed.
>
> I think this would work in this case.
Guenter,
Can you apply this patch on top of the series, and see if it makes the
warning go away?
diff --git a/include/linux/timer.h b/include/linux/timer.h
index d4d90149d015..e3c5f4bdd526 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -184,12 +184,23 @@ static inline int timer_pending(const struct timer_list * timer)
return !hlist_unhashed_lockless(&timer->entry);
}
+extern int __del_timer(struct timer_list * timer, bool free);
+
extern void add_timer_on(struct timer_list *timer, int cpu);
-extern int del_timer(struct timer_list * timer);
extern int mod_timer(struct timer_list *timer, unsigned long expires);
extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
extern int timer_reduce(struct timer_list *timer, unsigned long expires);
+static inline int del_timer_try_shutdown(struct timer_list *timer)
+{
+ return __del_timer(timer, true);
+}
+
+static inline int del_timer(struct timer_list *timer)
+{
+ return __del_timer(timer, false);
+}
+
/*
* The jiffies value which is added to now, when there is no timer
* in the timer wheel:
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 7305c65ad0eb..073031cb3bb9 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1255,7 +1255,7 @@ EXPORT_SYMBOL_GPL(add_timer_on);
* (ie. del_timer() of an inactive timer returns 0, del_timer() of an
* active timer returns 1.)
*/
-int del_timer(struct timer_list *timer)
+int __del_timer(struct timer_list *timer, bool free)
{
struct timer_base *base;
unsigned long flags;
@@ -1266,12 +1266,16 @@ int del_timer(struct timer_list *timer)
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
ret = detach_if_pending(timer, base, true);
+ if (free && ret) {
+ timer->function = NULL;
+ debug_timer_deactivate(timer);
+ }
raw_spin_unlock_irqrestore(&base->lock, flags);
}
return ret;
}
-EXPORT_SYMBOL(del_timer);
+EXPORT_SYMBOL(__del_timer);
static int __try_to_del_timer_sync(struct timer_list *timer, bool free)
{
diff --git a/net/core/sock.c b/net/core/sock.c
index 10cc84379d75..23a97442a0a6 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3345,7 +3345,7 @@ EXPORT_SYMBOL(sk_reset_timer);
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
- if (del_timer(timer))
+ if (del_timer_try_shutdown(timer))
__sock_put(sk);
}
EXPORT_SYMBOL(sk_stop_timer);
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 21:07 ` Steven Rostedt
@ 2022-10-27 21:15 ` Steven Rostedt
2022-10-27 22:35 ` Steven Rostedt
1 sibling, 0 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 21:15 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 27 Oct 2022 17:07:20 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> > And maybe that function can also disallow any future re-arming even
> > for the case where the timer couldn't be actively removed.
The naming of the functions will depend on this.
If the async version always shuts down the timer, then we should have the
interface be:
del_timer_shutdown() <- async
del_timer_shutdown_sync <- sync
As it would match the del_timer() and del_timer_sync() semantics.
If shutdown only happens if the timer is removed, then I believe the
current approach of del_timer_shutdown() being synchronous and
del_timer_try_shutdown() being async is the way to go, as it follows more
the semantics of mutex_lock() and mutex_trylock().
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-27 20:42 ` Steven Rostedt
@ 2022-10-27 21:22 ` Steven Rostedt
0 siblings, 0 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 21:22 UTC (permalink / raw)
To: Alan Stern
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Guenter Roeck, Greg Kroah-Hartman, Felipe Balbi, Johan Hovold,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb
On Thu, 27 Oct 2022 16:42:27 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Thu, 27 Oct 2022 16:38:19 -0400
> Alan Stern <stern@rowland.harvard.edu> wrote:
>
> > On Thu, Oct 27, 2022 at 11:05:45AM -0400, Steven Rostedt wrote:
> > > From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
> > >
> > > Before a timer is freed, del_timer_shutdown() must be called.
> >
> > Is this supposed to be true for all timers? Because the USB subsystem
> > contains an awful lot more timers than just the two you touched in this
> > patch.
>
> Yes, and this does mean that we are going to have to painstakingly find and
> fix ever one of them. This is why the last patch updates
> DEBUG_OBJECTS_TIMERS to detect cases where I miss.
BTW, as del_timer_shutdown() prevents the timer from being re-armed, there
are lots of timers in the kernel where I did not touch, because I could not
tell if the del_timer_sync() or the buggy del_timer() calls were for it to
be freed, or for some other legitimate reason, and I just stayed well enough
alone.
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 21:07 ` Steven Rostedt
2022-10-27 21:15 ` Steven Rostedt
@ 2022-10-27 22:35 ` Steven Rostedt
2022-10-28 22:31 ` Steven Rostedt
1 sibling, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-27 22:35 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 27 Oct 2022 17:07:20 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> Well, I think this current use case will break if we prevent the timer from
> being rearmed or run again if it's not found. But as you said, the
> networking folks need to confirm or deny it.
>
> The fact that it does the sock_put() when it removes the timer makes me
> think that it can be called again, and we shouldn't prevent that from
> happening.
>
> The debug code will let us know too, as it only "frees" it for freeing if
> it deactivated the timer and shut it down.
I think we have our answer from Guenter's report:
Linux version 6.1.0-rc2-00138-gced58c742836 (groeck@jupiter) (aarch64-linux-gcc (GCC) 11.3.0, GNU ld (GNU Binutils) 2.39) #1 SMP PREEMPT Thu Oct 27 14:53:17 PDT 2022
[ 17.258727] ------------[ cut here ]------------
[ 17.259079] ODEBUG: free active (active state 0) object type: timer_list hint: tcp_write_timer+0x0/0x190
[ 17.259723] WARNING: CPU: 0 PID: 309 at lib/debugobjects.c:502 debug_print_object+0xb8/0x100
[ 17.259951] Modules linked in:
[ 17.260249] CPU: 0 PID: 309 Comm: telnet Tainted: G N 6.1.0-rc2-00138-gced58c742836 #1
[ 17.260518] Hardware name: linux,dummy-virt (DT)
[ 17.260779] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 17.260967] pc : debug_print_object+0xb8/0x100
[ 17.261096] lr : debug_print_object+0xb8/0x100
[ 17.261223] sp : ffff8000086539e0
[ 17.261324] x29: ffff8000086539e0 x28: 0000000000000004 x27: ffff0d2ac2168000
[ 17.261574] x26: 0000000000000000 x25: ffffa241e2b9de18 x24: ffffa241e4f8fcd8
[ 17.261772] x23: ffffa241e336b370 x22: ffffa241e2b9de18 x21: ffff0d2ac20c5710
[ 17.261967] x20: ffffa241e4ea2568 x19: ffffa241e3ea3c00 x18: 00000000ffffffff
[ 17.262161] x17: 6c6973742068696e x16: 3a2074696d65725f x15: 6563742074797065
[ 17.262375] x14: 65203029206f626a x13: ffffa241e3ec7640 x12: 0000000000000d50
[ 17.262591] x11: 0000000000000470 x10: ffffa241e3f1f640 x9 : ffffa241e3ec7640
[ 17.262821] x8 : 00000000ffffefff x7 : ffffa241e3f1f640 x6 : 0000000000000000
[ 17.263028] x5 : ffff0d2adfebba68 x4 : 0000000000000000 x3 : 0000000000000027
[ 17.263235] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0d2ac658b340
[ 17.263528] Call trace:
[ 17.263646] debug_print_object+0xb8/0x100
[ 17.263795] __debug_check_no_obj_freed+0x1d0/0x25c
[ 17.263927] debug_check_no_obj_freed+0x20/0x90
[ 17.264051] slab_free_freelist_hook.constprop.0+0xac/0x1b0
[ 17.264197] kmem_cache_free+0x1ac/0x500
[ 17.264311] __sk_destruct+0x140/0x2a0
[ 17.264425] sk_destruct+0x54/0x64
[ 17.264531] __sk_free+0x74/0x120
[ 17.264636] sk_free+0x64/0x8c
[ 17.264736] tcp_close+0x94/0xc0
[ 17.264840] inet_release+0x50/0xb0
[ 17.264949] __sock_release+0x44/0xbc
[ 17.265061] sock_close+0x18/0x30
[ 17.265166] __fput+0x84/0x270
[ 17.265266] ____fput+0x10/0x20
[ 17.265366] task_work_run+0x88/0xf0
[ 17.265491] do_exit+0x334/0xafc
[ 17.265596] do_group_exit+0x34/0x90
[ 17.265705] __arm64_sys_exit_group+0x18/0x20
[ 17.265826] invoke_syscall+0x48/0x114
[ 17.265941] el0_svc_common.constprop.0+0x60/0x11c
[ 17.266070] do_el0_svc+0x30/0xd0
[ 17.266175] el0_svc+0x48/0xc0
[ 17.266276] el0t_64_sync_handler+0xbc/0x13c
[ 17.266396] el0t_64_sync+0x18c/0x190
[ 17.266565] irq event stamp: 5192
[ 17.266676] hardirqs last enabled at (5191): [<ffffa241e1926a18>] __up_console_sem+0x78/0x84
[ 17.266903] hardirqs last disabled at (5192): [<ffffa241e2b4d504>] el1_dbg+0x24/0x90
[ 17.267093] softirqs last enabled at (5170): [<ffffa241e181050c>] __do_softirq+0x46c/0x5d8
[ 17.267305] softirqs last disabled at (5163): [<ffffa241e1816750>] ____do_softirq+0x10/0x20
[ 17.267506] ---[ end trace 0000000000000000 ]---
[ 17.275715] ------------[ cut here ]------------
I'll go modify that code to make it shutdown even if it returns zero.
I thinks this means we'll need to change the name to:
del_timer_shutdown()
del_timer_shutdown_sync()
But I want to confirm this first.
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
[not found] ` <20221028021815.3130-1-hdanton@sina.com>
@ 2022-10-28 3:17 ` Steven Rostedt
0 siblings, 0 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 3:17 UTC (permalink / raw)
To: Hillf Danton; +Cc: linux-kernel, Alan Stern, Dan Carpenter, linux-usb
On Fri, 28 Oct 2022 10:18:15 +0800
Hillf Danton <hdanton@sina.com> wrote:
> On 27 Oct 2022 11:05:45 -0400 Steven Rostedt (Google) <rostedt@goodmis.org>
> >
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -1261,6 +1261,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
> >
> > /* Don't do a long sleep inside a workqueue routine */
> > if (type == HUB_INIT2) {
> > + /* Timers must be shutdown before they are re-initialized */
> > + if (hub->init_work.work.func)
> > + del_timer_shutdown(&hub->init_work.timer);
>
> This is not needed in the workqueue callback as the timer in question
> is not pending.
This was added because of the updates to DEBUG_OBJECTS_TIMERS that changed
it to require a shutdown to remove the activation of the timer. This is to
detect the possibility that a timer may become active just before freeing
(there's way too many bugs that show that code logic is not enough).
This code in particular is troubling because it re-initializes an already
initialized timer with a new function. This causes the debug-objects to
trigger an "object activated while initializing" warning.
I originally added the "shutdown" to deactivate the object before you
re-initialize it. But I have since updated the code to keep track of if it
was ever activated, and if so, not to call the init code again, so this may
not be required anymore.
I'm still trying to work out the kinks as the users of timers have become
adapted to the implementation, and may need to add some other helpers to
make this work.
-- Steve
>
> > INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
> > queue_delayed_work(system_power_efficient_wq,
> > &hub->init_work,
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-27 15:05 ` [RFC][PATCH v2 20/31] timers: usb: " Steven Rostedt
2022-10-27 20:38 ` Alan Stern
@ 2022-10-28 5:23 ` Guenter Roeck
2022-10-28 10:14 ` Steven Rostedt
2022-10-28 18:01 ` Steven Rostedt
1 sibling, 2 replies; 37+ messages in thread
From: Guenter Roeck @ 2022-10-28 5:23 UTC (permalink / raw)
To: Steven Rostedt, linux-kernel
Cc: Linus Torvalds, Thomas Gleixner, Stephen Boyd, Greg Kroah-Hartman,
Felipe Balbi, Johan Hovold, Alan Stern, Mathias Nyman,
Kai-Heng Feng, Matthias Kaehlcke, Michael Grzeschik,
Bhuvanesh Surachari, Dan Carpenter, linux-usb
On 10/27/22 08:05, Steven Rostedt wrote:
> From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
>
> Before a timer is freed, del_timer_shutdown() must be called.
>
> Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home/
>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Felipe Balbi <balbi@kernel.org>
> Cc: Johan Hovold <johan@kernel.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Mathias Nyman <mathias.nyman@linux.intel.com>
> Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Cc: Matthias Kaehlcke <mka@chromium.org>
> Cc: Michael Grzeschik <m.grzeschik@pengutronix.de>
> Cc: Bhuvanesh Surachari <Bhuvanesh_Surachari@mentor.com>
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> ---
> drivers/usb/core/hub.c | 3 +++
> drivers/usb/gadget/udc/m66592-udc.c | 2 +-
> drivers/usb/serial/garmin_gps.c | 2 +-
> drivers/usb/serial/mos7840.c | 2 +-
> 4 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index bbab424b0d55..397f263ab7da 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -1261,6 +1261,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
>
> /* Don't do a long sleep inside a workqueue routine */
> if (type == HUB_INIT2) {
> + /* Timers must be shutdown before they are re-initialized */
> + if (hub->init_work.work.func)
> + del_timer_shutdown(&hub->init_work.timer);
> INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
A similar call to INIT_DELAYED_WORK() around line 1085 needs the same change.
It would be great if that can somehow be hidden in INIT_DELAYED_WORK().
Thanks,
Guenter
> queue_delayed_work(system_power_efficient_wq,
> &hub->init_work,
> diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c
> index 931e6362a13d..a6e2f8358adf 100644
> --- a/drivers/usb/gadget/udc/m66592-udc.c
> +++ b/drivers/usb/gadget/udc/m66592-udc.c
> @@ -1519,7 +1519,7 @@ static int m66592_remove(struct platform_device *pdev)
>
> usb_del_gadget_udc(&m66592->gadget);
>
> - del_timer_sync(&m66592->timer);
> + del_timer_shutdown(&m66592->timer);
> iounmap(m66592->reg);
> free_irq(platform_get_irq(pdev, 0), m66592);
> m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
> diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
> index f1a8d8343623..2a53f26468bd 100644
> --- a/drivers/usb/serial/garmin_gps.c
> +++ b/drivers/usb/serial/garmin_gps.c
> @@ -1405,7 +1405,7 @@ static void garmin_port_remove(struct usb_serial_port *port)
>
> usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
> usb_kill_urb(port->interrupt_in_urb);
> - del_timer_sync(&garmin_data_p->timer);
> + del_timer_shutdown(&garmin_data_p->timer);
> kfree(garmin_data_p);
> }
>
> diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
> index 6b12bb4648b8..a90a706d27de 100644
> --- a/drivers/usb/serial/mos7840.c
> +++ b/drivers/usb/serial/mos7840.c
> @@ -1726,7 +1726,7 @@ static void mos7840_port_remove(struct usb_serial_port *port)
> mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
>
> del_timer_sync(&mos7840_port->led_timer1);
> - del_timer_sync(&mos7840_port->led_timer2);
> + del_timer_shutdown(&mos7840_port->led_timer2);
>
> usb_kill_urb(mos7840_port->led_urb);
> usb_free_urb(mos7840_port->led_urb);
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 5:23 ` Guenter Roeck
@ 2022-10-28 10:14 ` Steven Rostedt
2022-10-28 14:00 ` Steven Rostedt
2022-10-28 18:01 ` Steven Rostedt
1 sibling, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 10:14 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb
On Thu, 27 Oct 2022 22:23:06 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
> > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> > index bbab424b0d55..397f263ab7da 100644
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -1261,6 +1261,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
> >
> > /* Don't do a long sleep inside a workqueue routine */
> > if (type == HUB_INIT2) {
> > + /* Timers must be shutdown before they are re-initialized */
> > + if (hub->init_work.work.func)
> > + del_timer_shutdown(&hub->init_work.timer);
> > INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
>
> A similar call to INIT_DELAYED_WORK() around line 1085 needs the same change.
>
> It would be great if that can somehow be hidden in INIT_DELAYED_WORK().
I agree, but the delayed work is such a special case, I'm struggling to
find something that works sensibly. :-/
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 10:14 ` Steven Rostedt
@ 2022-10-28 14:00 ` Steven Rostedt
0 siblings, 0 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 14:00 UTC (permalink / raw)
To: Guenter Roeck, linux-scsi
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Lai Jiangshan, Tejun Heo, Jens Axboe, James E.J. Bottomley,
Martin K. Petersen
On Fri, 28 Oct 2022 06:14:22 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Thu, 27 Oct 2022 22:23:06 -0700
> Guenter Roeck <linux@roeck-us.net> wrote:
>
> > A similar call to INIT_DELAYED_WORK() around line 1085 needs the same change.
> >
> > It would be great if that can somehow be hidden in INIT_DELAYED_WORK().
>
> I agree, but the delayed work is such a special case, I'm struggling to
> find something that works sensibly. :-/
>
OK, I diagnosed the issue here. The problem is that delayed work also has no
"shutdown" method when it's done. Which means there's no generic way to
call the work->timer shutdown method. So we have two options to handle
delayed work timers:
1) Add special initialization for delayed work so that it can just go back
to the old checking (activating on arming, deactivating by any
del_timer*).
2) Implement a shutdown state for the work queues as well. There could
definitely be the same types of bugs as with timers, where a delayed
work could be pending on something that's been freed. That's probably
why there's a DEBUG_OBJECTS_WORK too.
Ideally, I would like to have #2, but realistically, I'm going for #1 for
now. We could always add the work queue shutdown state later if we want.
The problem with timers with respect to delayed work queues, is that there's
no place to add the "shutdown" before its no longer in use. Worse yet,
there's code that caches descriptors that have delayed work instead of
freeing them. (See block/blk-mq.c and drivers/scsi/scsi_lib.c with the queuelist).
Where it just calls del_timer(), and then sends it back to the free store
for reuse later. Perhaps we should add DEBUG_OBJECTS checking to these too?
Anyway, I'll make it where the INIT_DELAYED_WORK will call
__timer_init_work() that will set the debug state in the timer to
TIMER_DEBUG_WORK, were it will activate and deactivate the debug object on
add_timer() and del_timer() and hope that it's not one of the bugs we are
hitting :-/
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 21:07 ` Steven Rostedt
@ 2022-10-28 15:16 ` Guenter Roeck
0 siblings, 0 replies; 37+ messages in thread
From: Guenter Roeck @ 2022-10-28 15:16 UTC (permalink / raw)
To: Steven Rostedt, Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Jesse Brandeburg,
Tony Nguyen, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Mirko Lindner, Stephen Hemminger, Martin KaFai Lau,
Alexei Starovoitov, Kuniyuki Iwashima, Pavel Begunkov,
Menglong Dong, linux-usb, linux-wireless, bridge, netfilter-devel,
coreteam, lvs-devel, linux-afs, linux-nfs, tipc-discussion
On 10/27/22 14:07, Steven Rostedt wrote:
> On Thu, 27 Oct 2022 16:34:53 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
>
>> What about del_timer_try_shutdown(), that if it removes the timer, it sets
>> the function to NULL (making it equivalent to a successful shutdown),
>> otherwise it does nothing. Allowing the the timer to be rearmed.
>>
>> I think this would work in this case.
>
> Guenter,
>
> Can you apply this patch on top of the series, and see if it makes the
> warning go away?
>
That patch not only helps, it also fixes the crash seen with openrisc.
For that crash, I was able to collect some useful data; see the log below.
Thanks,
Guenter
---
WARNING: CPU: 0 PID: 7 at lib/debugobjects.c:502 debug_print_object+0xc0/0xe8
ODEBUG: free active (active state 0) object type: timer_list hint: rcu_lock_map+0x0/0x14
Modules linked in:
CPU: 0 PID: 7 Comm: ksoftirqd/0 Not tainted 6.1.0-rc2-00145-g2c4e85e9ac93 #1
Call trace:
[<048ecc8e>] dump_stack_lvl+0x44/0x80
[<c6a7029c>] dump_stack+0x1c/0x2c
[<b225e4eb>] __warn+0xdc/0x118
[<1070b766>] ? debug_print_object+0xc0/0xe8
[<57923a76>] warn_slowpath_fmt+0x78/0x90
[<1070b766>] debug_print_object+0xc0/0xe8
[<b3abbcb0>] __debug_check_no_obj_freed+0x230/0x2b8
[<508d9b5a>] ? delayed_put_task_struct+0x0/0x84
[<30f5a2a0>] ? _s_kernel_ro+0x0/0x200
[<403ab082>] debug_check_no_obj_freed+0x30/0x40
[<82702c56>] free_pcp_prepare+0xc4/0x2b0
[<508d9b5a>] ? delayed_put_task_struct+0x0/0x84
[<7798b190>] free_unref_page+0x44/0x210
[<d73717e5>] __free_pages+0x108/0x124
[<a32de4eb>] slob_free_pages+0x9c/0xac
[<bd51c171>] slob_free+0x40c/0x62c
[<a2d26e0e>] ? thread_stack_free_rcu+0x0/0x44
[<24b2df6c>] ? rcu_process_callbacks+0x114/0x224
[<24b2df6c>] ? rcu_process_callbacks+0x114/0x224
[<7794ec75>] ? rcu_process_callbacks+0xdc/0x224
[<7794ec75>] ? rcu_process_callbacks+0xdc/0x224
[<d76fe88f>] kmem_cache_free+0x64/0xa0
[<46d25dac>] free_task+0x7c/0xe0
[<2df25813>] __put_task_struct+0xe8/0x194
[<64f9675b>] delayed_put_task_struct+0x58/0x84
[<8755437e>] rcu_process_callbacks+0xf0/0x224
[<24b2df6c>] ? rcu_process_callbacks+0x114/0x224
[<020db442>] ? rcu_process_callbacks+0x178/0x224
[<87626af4>] __do_softirq+0x11c/0x2f8
[<c3f89a50>] ? smpboot_thread_fn+0x4c/0x304
[<c3f89a50>] ? smpboot_thread_fn+0x4c/0x304
[<021b0175>] ? smpboot_thread_fn+0x188/0x304
[<f2e79ebd>] ? smpboot_thread_fn+0x158/0x304
[<966be0e6>] run_ksoftirqd+0x4c/0x80
[<4bf65f60>] smpboot_thread_fn+0x180/0x304
[<3f914d93>] ? _raw_spin_unlock_irqrestore+0x50/0x84
[<bef37779>] ? __kthread_parkme+0x60/0xdc
[<b0798e10>] ? smpboot_thread_fn+0x0/0x304
[<c463cd92>] kthread+0x11c/0x144
[<3eaef0b7>] ? kthread+0x0/0x144
[<ef2f6228>] ret_from_fork+0x1c/0x84
---[ end trace 0000000000000000 ]---
Unable to handle kernel access
at virtual address 0xbd6ed6a4
Oops#: 0000
CPU #: 0
PC: c0056c78 SR: 00008679 SP: c1027c24
GPR00: 00000000 GPR01: c1027c24 GPR02: c1027c78 GPR03: 00008279
GPR04: 00000000 GPR05: 00000000 GPR06: 00000000 GPR07: 00000001
GPR08: 00000000 GPR09: c0056c64 GPR10: c1026000 GPR11: 00000000
GPR12: 00000000 GPR13: 00000001 GPR14: c05c0000 GPR15: 00000000
GPR16: 00000001 GPR17: bd6ed6a4 GPR18: ff4517b0 GPR19: fd145f00
GPR20: 00000000 GPR21: 00000000 GPR22: 00000000 GPR23: c0760000
GPR24: c10232a0 GPR25: 00000003 GPR26: 00000000 GPR27: 00000000
GPR28: c1a00458 GPR29: 00000000 GPR30: c0790000 GPR31: 00000000
RES: 00000000 oGPR11: ffffffff
Process ksoftirqd/0 (pid: 7, stackpage=c10232a0)
Stack:
Call trace:
[<6ce5cfad>] __lock_acquire.constprop.0+0xa8/0x914
[<4bc14e12>] ? __del_timer_sync+0x0/0x128
[<da915c87>] lock_acquire.part.0.isra.0+0xd4/0x1ac
[<4bc14e12>] ? __del_timer_sync+0x0/0x128
[<9b341df3>] lock_acquire+0x2c/0x44
[<233b5cbc>] __del_timer_sync+0x64/0x128
[<4bc14e12>] ? __del_timer_sync+0x0/0x128
[<05cd2741>] timer_fixup_free+0x34/0x5c
[<3fa496ad>] __debug_check_no_obj_freed+0x250/0x2b8
[<508d9b5a>] ? delayed_put_task_struct+0x0/0x84
[<30f5a2a0>] ? _s_kernel_ro+0x0/0x200
[<403ab082>] debug_check_no_obj_freed+0x30/0x40
[<82702c56>] free_pcp_prepare+0xc4/0x2b0
[<508d9b5a>] ? delayed_put_task_struct+0x0/0x84
[<7798b190>] free_unref_page+0x44/0x210
[<d73717e5>] __free_pages+0x108/0x124
[<a32de4eb>] slob_free_pages+0x9c/0xac
[<bd51c171>] slob_free+0x40c/0x62c
[<a2d26e0e>] ? thread_stack_free_rcu+0x0/0x44
[<24b2df6c>] ? rcu_process_callbacks+0x114/0x224
[<24b2df6c>] ? rcu_process_callbacks+0x114/0x224
[<7794ec75>] ? rcu_process_callbacks+0xdc/0x224
[<7794ec75>] ? rcu_process_callbacks+0xdc/0x224
[<d76fe88f>] kmem_cache_free+0x64/0xa0
[<46d25dac>] free_task+0x7c/0xe0
[<2df25813>] __put_task_struct+0xe8/0x194
[<64f9675b>] delayed_put_task_struct+0x58/0x84
[<8755437e>] rcu_process_callbacks+0xf0/0x224
[<24b2df6c>] ? rcu_process_callbacks+0x114/0x224
[<020db442>] ? rcu_process_callbacks+0x178/0x224
[<87626af4>] __do_softirq+0x11c/0x2f8
[<c3f89a50>] ? smpboot_thread_fn+0x4c/0x304
[<c3f89a50>] ? smpboot_thread_fn+0x4c/0x304
[<021b0175>] ? smpboot_thread_fn+0x188/0x304
[<f2e79ebd>] ? smpboot_thread_fn+0x158/0x304
[<966be0e6>] run_ksoftirqd+0x4c/0x80
[<4bf65f60>] smpboot_thread_fn+0x180/0x304
[<3f914d93>] ? _raw_spin_unlock_irqrestore+0x50/0x84
[<bef37779>] ? __kthread_parkme+0x60/0xdc
[<b0798e10>] ? smpboot_thread_fn+0x0/0x304
[<c463cd92>] kthread+0x11c/0x144
[<3eaef0b7>] ? kthread+0x0/0x144
[<ef2f6228>] ret_from_fork+0x1c/0x84
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 5:23 ` Guenter Roeck
2022-10-28 10:14 ` Steven Rostedt
@ 2022-10-28 18:01 ` Steven Rostedt
2022-10-28 18:10 ` Steven Rostedt
1 sibling, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 18:01 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Thu, 27 Oct 2022 22:23:06 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
> > index bbab424b0d55..397f263ab7da 100644
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -1261,6 +1261,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
> >
> > /* Don't do a long sleep inside a workqueue routine */
> > if (type == HUB_INIT2) {
> > + /* Timers must be shutdown before they are re-initialized */
> > + if (hub->init_work.work.func)
> > + del_timer_shutdown(&hub->init_work.timer);
> > INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);
>
> A similar call to INIT_DELAYED_WORK() around line 1085 needs the same change.
>
> It would be great if that can somehow be hidden in INIT_DELAYED_WORK().
I've decided to treat INIT_DELAYED_WORK() like it was before. It only
checks from the time the timer is added to the time it is removed without
needing a shutdown call. That's because there's no API in the workqueue
code that allows for us to require a shutdown on the INIT_DELAYED_WORK's
timer.
Guenter,
Can you remove all the extra patches that touched the timer.h and timer.c
code, and replace the last patch with this, and then try again?
-- Steve
include/linux/timer.h | 38 +++++++++++++++++++++++++++--
include/linux/workqueue.h | 4 ++--
kernel/time/timer.c | 50 ++++++++++++++++++++++++++++++++++-----
kernel/workqueue.c | 12 ++++++++++
4 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 45392b0ac2e1..27e3a8676ff8 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -8,6 +8,12 @@
#include <linux/debugobjects.h>
#include <linux/stringify.h>
+enum timer_debug_state {
+ TIMER_DEBUG_DISABLED,
+ TIMER_DEBUG_ENABLED,
+ TIMER_DEBUG_WORK,
+};
+
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
@@ -18,6 +24,9 @@ struct timer_list {
void (*function)(struct timer_list *);
u32 flags;
+#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
+ enum timer_debug_state enabled;
+#endif
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
@@ -128,6 +137,31 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
init_timer_on_stack_key((_timer), (_fn), (_flags), NULL, NULL)
#endif
+#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
+#define __init_timer_debug(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_DISABLED; \
+ __init_timer((_timer), (_fn), (_flags)); \
+ } while (0)
+#define __init_timer_work(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_WORK; \
+ __init_timer((_timer), (_fn), (_flags)); \
+ } while (0)
+#define __init_timer_work_on_stack(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_WORK; \
+ __init_timer_on_stack((_timer), (_fn), (_flags)); \
+ } while (0)
+#else
+#define __init_timer_debug(_timer, _fn, _flags) \
+ __init_timer((_timer), (_fn), (_flags))
+#define __init_timer_work(_timer, _fn, _flags) \
+ __init_timer((_timer), (_fn), (_flags))
+#define __init_timer_work_on_stack(_timer, _fn, _flags) \
+ __init_timer_on_stack((_timer), (_fn), (_flags))
+#endif
+
/**
* timer_setup - prepare a timer for first use
* @timer: the timer in question
@@ -139,7 +173,7 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
* be used and must be balanced with a call to destroy_timer_on_stack().
*/
#define timer_setup(timer, callback, flags) \
- __init_timer((timer), (callback), (flags))
+ __init_timer_debug((timer), (callback), (flags))
#define timer_setup_on_stack(timer, callback, flags) \
__init_timer_on_stack((timer), (callback), (flags))
@@ -243,7 +277,7 @@ static inline int del_timer_shutdown(struct timer_list *timer)
return __del_timer_sync(timer, true);
}
-#define del_singleshot_timer_sync(t) del_timer_sync(t)
+#define del_singleshot_timer_sync(t) del_timer_shutdown(t)
extern void init_timers(void);
struct hrtimer;
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index a0143dd24430..290c96429ce1 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -250,7 +250,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
#define __INIT_DELAYED_WORK(_work, _func, _tflags) \
do { \
INIT_WORK(&(_work)->work, (_func)); \
- __init_timer(&(_work)->timer, \
+ __init_timer_work(&(_work)->timer, \
delayed_work_timer_fn, \
(_tflags) | TIMER_IRQSAFE); \
} while (0)
@@ -258,7 +258,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
#define __INIT_DELAYED_WORK_ONSTACK(_work, _func, _tflags) \
do { \
INIT_WORK_ONSTACK(&(_work)->work, (_func)); \
- __init_timer_on_stack(&(_work)->timer, \
+ __init_timer_work_on_stack(&(_work)->timer, \
delayed_work_timer_fn, \
(_tflags) | TIMER_IRQSAFE); \
} while (0)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 5179ac2335a0..9a921843cc4f 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -691,7 +691,11 @@ static bool timer_fixup_init(void *addr, enum debug_obj_state state)
switch (state) {
case ODEBUG_STATE_ACTIVE:
- del_timer_sync(timer);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_ENABLED;
+ del_timer_shutdown(timer);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_DISABLED;
debug_object_init(timer, &timer_debug_descr);
return true;
default:
@@ -737,8 +741,10 @@ static bool timer_fixup_free(void *addr, enum debug_obj_state state)
switch (state) {
case ODEBUG_STATE_ACTIVE:
- del_timer_sync(timer);
+ del_timer_shutdown(timer);
debug_object_free(timer, &timer_debug_descr);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_DISABLED;
return true;
default:
return false;
@@ -774,16 +780,36 @@ static const struct debug_obj_descr timer_debug_descr = {
static inline void debug_timer_init(struct timer_list *timer)
{
+ if (timer->enabled == TIMER_DEBUG_ENABLED)
+ return;
+
debug_object_init(timer, &timer_debug_descr);
}
static inline void debug_timer_activate(struct timer_list *timer)
{
+ if (timer->enabled == TIMER_DEBUG_ENABLED)
+ return;
+
+ if (timer->enabled == TIMER_DEBUG_DISABLED)
+ timer->enabled = TIMER_DEBUG_ENABLED;
+
debug_object_activate(timer, &timer_debug_descr);
}
-static inline void debug_timer_deactivate(struct timer_list *timer)
+static inline void debug_timer_deactivate(struct timer_list *timer, bool free)
{
+ switch (timer->enabled) {
+ case TIMER_DEBUG_DISABLED:
+ return;
+ case TIMER_DEBUG_ENABLED:
+ if (!free)
+ return;
+ timer->enabled = TIMER_DEBUG_DISABLED;
+ break;
+ case TIMER_DEBUG_WORK:
+ break;
+ }
debug_object_deactivate(timer, &timer_debug_descr);
}
@@ -813,6 +839,14 @@ void destroy_timer_on_stack(struct timer_list *timer)
}
EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
+static struct timer_base *lock_timer_base(struct timer_list *timer,
+ unsigned long *flags);
+
+void __timer_reinit_debug_objects(struct timer_list *timer)
+{
+ return;
+}
+
#else
static inline void debug_timer_init(struct timer_list *timer) { }
static inline void debug_timer_activate(struct timer_list *timer) { }
@@ -828,7 +862,7 @@ static inline void debug_init(struct timer_list *timer)
static inline void debug_deactivate(struct timer_list *timer)
{
- debug_timer_deactivate(timer);
+ debug_timer_deactivate(timer, false);
trace_timer_cancel(timer);
}
@@ -1251,8 +1285,10 @@ int __del_timer(struct timer_list *timer, bool free)
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
ret = detach_if_pending(timer, base, true);
- if (free && ret)
+ if (free) {
timer->function = NULL;
+ debug_timer_deactivate(timer, true);
+ }
raw_spin_unlock_irqrestore(&base->lock, flags);
}
@@ -1272,8 +1308,10 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool free)
if (base->running_timer != timer)
ret = detach_if_pending(timer, base, true);
- if (free)
+ if (free) {
timer->function = NULL;
+ debug_timer_deactivate(timer, true);
+ }
raw_spin_unlock_irqrestore(&base->lock, flags);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 47a7124bbea4..9a48213fc4e4 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1225,6 +1225,16 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, unsigned long work_
put_pwq(pwq);
}
+static void deactivate_timer(struct work_struct *work, bool is_dwork)
+{
+ struct delayed_work *dwork;
+
+ if (!is_dwork)
+ return;
+
+ dwork = to_delayed_work(work);
+}
+
/**
* try_to_grab_pending - steal work item from worklist and disable irq
* @work: work item to steal
@@ -3148,6 +3158,8 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
}
} while (unlikely(ret < 0));
+ deactivate_timer(work, is_dwork);
+
/* tell other tasks trying to grab @work to back off */
mark_work_canceling(work);
local_irq_restore(flags);
--
2.35.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 18:01 ` Steven Rostedt
@ 2022-10-28 18:10 ` Steven Rostedt
2022-10-28 19:59 ` Guenter Roeck
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 18:10 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Fri, 28 Oct 2022 14:01:29 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> @@ -813,6 +839,14 @@ void destroy_timer_on_stack(struct timer_list *timer)
> }
> EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
>
> +static struct timer_base *lock_timer_base(struct timer_list *timer,
> + unsigned long *flags);
> +
> +void __timer_reinit_debug_objects(struct timer_list *timer)
> +{
> + return;
> +}
> +
> #else
> static inline void debug_timer_init(struct timer_list *timer) { }
> static inline void debug_timer_activate(struct timer_list *timer) { }
Bah, the above chunk was leftover from some debugging.
Updated patch:
-- Steve
include/linux/timer.h | 38 +++++++++++++++++++++++++++++++++--
include/linux/workqueue.h | 4 ++--
kernel/time/timer.c | 42 +++++++++++++++++++++++++++++++++------
kernel/workqueue.c | 12 +++++++++++
4 files changed, 86 insertions(+), 10 deletions(-)
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 45392b0ac2e1..27e3a8676ff8 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -8,6 +8,12 @@
#include <linux/debugobjects.h>
#include <linux/stringify.h>
+enum timer_debug_state {
+ TIMER_DEBUG_DISABLED,
+ TIMER_DEBUG_ENABLED,
+ TIMER_DEBUG_WORK,
+};
+
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
@@ -18,6 +24,9 @@ struct timer_list {
void (*function)(struct timer_list *);
u32 flags;
+#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
+ enum timer_debug_state enabled;
+#endif
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
@@ -128,6 +137,31 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
init_timer_on_stack_key((_timer), (_fn), (_flags), NULL, NULL)
#endif
+#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
+#define __init_timer_debug(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_DISABLED; \
+ __init_timer((_timer), (_fn), (_flags)); \
+ } while (0)
+#define __init_timer_work(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_WORK; \
+ __init_timer((_timer), (_fn), (_flags)); \
+ } while (0)
+#define __init_timer_work_on_stack(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_WORK; \
+ __init_timer_on_stack((_timer), (_fn), (_flags)); \
+ } while (0)
+#else
+#define __init_timer_debug(_timer, _fn, _flags) \
+ __init_timer((_timer), (_fn), (_flags))
+#define __init_timer_work(_timer, _fn, _flags) \
+ __init_timer((_timer), (_fn), (_flags))
+#define __init_timer_work_on_stack(_timer, _fn, _flags) \
+ __init_timer_on_stack((_timer), (_fn), (_flags))
+#endif
+
/**
* timer_setup - prepare a timer for first use
* @timer: the timer in question
@@ -139,7 +173,7 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
* be used and must be balanced with a call to destroy_timer_on_stack().
*/
#define timer_setup(timer, callback, flags) \
- __init_timer((timer), (callback), (flags))
+ __init_timer_debug((timer), (callback), (flags))
#define timer_setup_on_stack(timer, callback, flags) \
__init_timer_on_stack((timer), (callback), (flags))
@@ -243,7 +277,7 @@ static inline int del_timer_shutdown(struct timer_list *timer)
return __del_timer_sync(timer, true);
}
-#define del_singleshot_timer_sync(t) del_timer_sync(t)
+#define del_singleshot_timer_sync(t) del_timer_shutdown(t)
extern void init_timers(void);
struct hrtimer;
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index a0143dd24430..290c96429ce1 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -250,7 +250,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
#define __INIT_DELAYED_WORK(_work, _func, _tflags) \
do { \
INIT_WORK(&(_work)->work, (_func)); \
- __init_timer(&(_work)->timer, \
+ __init_timer_work(&(_work)->timer, \
delayed_work_timer_fn, \
(_tflags) | TIMER_IRQSAFE); \
} while (0)
@@ -258,7 +258,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
#define __INIT_DELAYED_WORK_ONSTACK(_work, _func, _tflags) \
do { \
INIT_WORK_ONSTACK(&(_work)->work, (_func)); \
- __init_timer_on_stack(&(_work)->timer, \
+ __init_timer_work_on_stack(&(_work)->timer, \
delayed_work_timer_fn, \
(_tflags) | TIMER_IRQSAFE); \
} while (0)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 5179ac2335a0..ac2e8beb4235 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -691,7 +691,11 @@ static bool timer_fixup_init(void *addr, enum debug_obj_state state)
switch (state) {
case ODEBUG_STATE_ACTIVE:
- del_timer_sync(timer);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_ENABLED;
+ del_timer_shutdown(timer);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_DISABLED;
debug_object_init(timer, &timer_debug_descr);
return true;
default:
@@ -737,8 +741,10 @@ static bool timer_fixup_free(void *addr, enum debug_obj_state state)
switch (state) {
case ODEBUG_STATE_ACTIVE:
- del_timer_sync(timer);
+ del_timer_shutdown(timer);
debug_object_free(timer, &timer_debug_descr);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_DISABLED;
return true;
default:
return false;
@@ -774,16 +780,36 @@ static const struct debug_obj_descr timer_debug_descr = {
static inline void debug_timer_init(struct timer_list *timer)
{
+ if (timer->enabled == TIMER_DEBUG_ENABLED)
+ return;
+
debug_object_init(timer, &timer_debug_descr);
}
static inline void debug_timer_activate(struct timer_list *timer)
{
+ if (timer->enabled == TIMER_DEBUG_ENABLED)
+ return;
+
+ if (timer->enabled == TIMER_DEBUG_DISABLED)
+ timer->enabled = TIMER_DEBUG_ENABLED;
+
debug_object_activate(timer, &timer_debug_descr);
}
-static inline void debug_timer_deactivate(struct timer_list *timer)
+static inline void debug_timer_deactivate(struct timer_list *timer, bool free)
{
+ switch (timer->enabled) {
+ case TIMER_DEBUG_DISABLED:
+ return;
+ case TIMER_DEBUG_ENABLED:
+ if (!free)
+ return;
+ timer->enabled = TIMER_DEBUG_DISABLED;
+ break;
+ case TIMER_DEBUG_WORK:
+ break;
+ }
debug_object_deactivate(timer, &timer_debug_descr);
}
@@ -828,7 +854,7 @@ static inline void debug_init(struct timer_list *timer)
static inline void debug_deactivate(struct timer_list *timer)
{
- debug_timer_deactivate(timer);
+ debug_timer_deactivate(timer, false);
trace_timer_cancel(timer);
}
@@ -1251,8 +1277,10 @@ int __del_timer(struct timer_list *timer, bool free)
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
ret = detach_if_pending(timer, base, true);
- if (free && ret)
+ if (free) {
timer->function = NULL;
+ debug_timer_deactivate(timer, true);
+ }
raw_spin_unlock_irqrestore(&base->lock, flags);
}
@@ -1272,8 +1300,10 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool free)
if (base->running_timer != timer)
ret = detach_if_pending(timer, base, true);
- if (free)
+ if (free) {
timer->function = NULL;
+ debug_timer_deactivate(timer, true);
+ }
raw_spin_unlock_irqrestore(&base->lock, flags);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 47a7124bbea4..9a48213fc4e4 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1225,6 +1225,16 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, unsigned long work_
put_pwq(pwq);
}
+static void deactivate_timer(struct work_struct *work, bool is_dwork)
+{
+ struct delayed_work *dwork;
+
+ if (!is_dwork)
+ return;
+
+ dwork = to_delayed_work(work);
+}
+
/**
* try_to_grab_pending - steal work item from worklist and disable irq
* @work: work item to steal
@@ -3148,6 +3158,8 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
}
} while (unlikely(ret < 0));
+ deactivate_timer(work, is_dwork);
+
/* tell other tasks trying to grab @work to back off */
mark_work_canceling(work);
local_irq_restore(flags);
--
2.35.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 18:10 ` Steven Rostedt
@ 2022-10-28 19:59 ` Guenter Roeck
2022-10-28 20:40 ` Steven Rostedt
2022-10-29 14:52 ` Guenter Roeck
0 siblings, 2 replies; 37+ messages in thread
From: Guenter Roeck @ 2022-10-28 19:59 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Fri, Oct 28, 2022 at 02:10:07PM -0400, Steven Rostedt wrote:
> On Fri, 28 Oct 2022 14:01:29 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
>
> > @@ -813,6 +839,14 @@ void destroy_timer_on_stack(struct timer_list *timer)
> > }
> > EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
> >
> > +static struct timer_base *lock_timer_base(struct timer_list *timer,
> > + unsigned long *flags);
> > +
> > +void __timer_reinit_debug_objects(struct timer_list *timer)
> > +{
> > + return;
> > +}
> > +
> > #else
> > static inline void debug_timer_init(struct timer_list *timer) { }
> > static inline void debug_timer_activate(struct timer_list *timer) { }
>
> Bah, the above chunk was leftover from some debugging.
>
I'll test again with the following changes on top of your published
patch series. I hope this is the current status, but I may have lost
something.
Looking into it ... deactivate_timer() doesn't do anything
and seems wrong. Did I miss something ?
Thanks,
Guenter
---
diff --git a/block/blk-core.c b/block/blk-core.c
index 17667159482e..69b1daa2e91a 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -227,7 +227,7 @@ const char *blk_status_to_str(blk_status_t status)
*/
void blk_sync_queue(struct request_queue *q)
{
- del_timer_sync(&q->timeout);
+ del_timer_shutdown(&q->timeout);
cancel_work_sync(&q->timeout_work);
}
EXPORT_SYMBOL(blk_sync_queue);
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index e71b3b43927c..12a1e46536ed 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -769,6 +769,8 @@ static void blk_release_queue(struct kobject *kobj)
percpu_ref_exit(&q->q_usage_counter);
+ blk_sync_queue(q);
+
if (q->poll_stat)
blk_stat_remove_callback(q, q->poll_cb);
blk_stat_free_callback(q->poll_cb);
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index ecfad43df45a..0c86066929d3 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -770,8 +770,6 @@ static void tulip_down (struct net_device *dev)
spin_unlock_irqrestore (&tp->lock, flags);
- timer_setup(&tp->timer, tulip_tbl[tp->chip_id].media_timer, 0);
-
dev->if_port = tp->saved_if_port;
/* Leave the driver in snooze, not sleep, mode. */
@@ -1869,10 +1867,14 @@ static int __maybe_unused tulip_resume(struct device *dev_d)
static void tulip_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct tulip_private *tp;
if (!dev)
return;
+ tp = netdev_priv(dev);
+ del_timer_shutdown(&tp->timer);
+
unregister_netdev(dev);
}
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index 4547ac44c8d4..50dbd2ea23fc 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -73,7 +73,7 @@ int parport_wait_event (struct parport *port, signed long timeout)
timer_setup(&port->timer, timeout_waiting_on_port, 0);
mod_timer(&port->timer, jiffies + timeout);
ret = down_interruptible (&port->physport->ieee1284.irq);
- if (!del_timer_sync(&port->timer) && !ret)
+ if (!del_timer_shutdown(&port->timer) && !ret)
/* Timed out. */
ret = 1;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 63f32f843e75..b91b27c398ae 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -789,7 +789,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code)
while (!list_empty(&hostdata->sent)) {
evt = list_first_entry(&hostdata->sent, struct srp_event_struct, list);
list_del(&evt->list);
- del_timer(&evt->timer);
+ del_timer_try_shutdown(&evt->timer);
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
if (evt->cmnd) {
@@ -944,7 +944,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
be64_to_cpu(crq_as_u64[1]));
if (rc != 0) {
list_del(&evt_struct->list);
- del_timer(&evt_struct->timer);
+ del_timer_shutdown(&evt_struct->timer);
/* If send_crq returns H_CLOSED, return SCSI_MLQUEUE_HOST_BUSY.
* Firmware will send a CRQ with a transport event (0xFF) to
@@ -1840,7 +1840,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
atomic_add(be32_to_cpu(evt_struct->xfer_iu->srp.rsp.req_lim_delta),
&hostdata->request_limit);
- del_timer(&evt_struct->timer);
+ del_timer_shutdown(&evt_struct->timer);
if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd)
evt_struct->cmnd->result = DID_ERROR << 16;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 397f263ab7da..7d1f7a89a5ea 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1082,6 +1082,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
delay = hub_power_on_good_delay(hub);
hub_power_on(hub, false);
+ /* Timers must be shutdown before they are re-initialized */
+ if (hub->init_work.work.func)
+ del_timer_shutdown(&hub->init_work.timer);
INIT_DELAYED_WORK(&hub->init_work, hub_init_func2);
queue_delayed_work(system_power_efficient_wq,
&hub->init_work,
diff --git a/include/linux/timer.h b/include/linux/timer.h
index d4d90149d015..4dfb3913bb69 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -8,6 +8,12 @@
#include <linux/debugobjects.h>
#include <linux/stringify.h>
+enum timer_debug_state {
+ TIMER_DEBUG_DISABLED,
+ TIMER_DEBUG_ENABLED,
+ TIMER_DEBUG_WORK,
+};
+
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
@@ -19,7 +25,7 @@ struct timer_list {
u32 flags;
#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
- u32 enabled;
+ enum timer_debug_state enabled;
#endif
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
@@ -134,14 +140,26 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
#define __init_timer_debug(_timer, _fn, _flags) \
do { \
- (_timer)->enabled = 0; \
+ (_timer)->enabled = TIMER_DEBUG_DISABLED; \
__init_timer((_timer), (_fn), (_flags)); \
} while (0)
-#else
-#define __init_timer_debug(_timer, _fn, _flags) \
+#define __init_timer_work(_timer, _fn, _flags) \
do { \
+ (_timer)->enabled = TIMER_DEBUG_WORK; \
__init_timer((_timer), (_fn), (_flags)); \
} while (0)
+#define __init_timer_work_on_stack(_timer, _fn, _flags) \
+ do { \
+ (_timer)->enabled = TIMER_DEBUG_WORK; \
+ __init_timer_on_stack((_timer), (_fn), (_flags)); \
+ } while (0)
+#else
+#define __init_timer_debug(_timer, _fn, _flags) \
+ __init_timer((_timer), (_fn), (_flags))
+#define __init_timer_work(_timer, _fn, _flags) \
+ __init_timer((_timer), (_fn), (_flags))
+#define __init_timer_work_on_stack(_timer, _fn, _flags) \
+ __init_timer_on_stack((_timer), (_fn), (_flags))
#endif
/**
@@ -184,12 +202,23 @@ static inline int timer_pending(const struct timer_list * timer)
return !hlist_unhashed_lockless(&timer->entry);
}
+extern int __del_timer(struct timer_list * timer, bool free);
+
extern void add_timer_on(struct timer_list *timer, int cpu);
-extern int del_timer(struct timer_list * timer);
extern int mod_timer(struct timer_list *timer, unsigned long expires);
extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
extern int timer_reduce(struct timer_list *timer, unsigned long expires);
+static inline int del_timer_try_shutdown(struct timer_list *timer)
+{
+ return __del_timer(timer, true);
+}
+
+static inline int del_timer(struct timer_list *timer)
+{
+ return __del_timer(timer, false);
+}
+
/*
* The jiffies value which is added to now, when there is no timer
* in the timer wheel:
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index a0143dd24430..290c96429ce1 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -250,7 +250,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
#define __INIT_DELAYED_WORK(_work, _func, _tflags) \
do { \
INIT_WORK(&(_work)->work, (_func)); \
- __init_timer(&(_work)->timer, \
+ __init_timer_work(&(_work)->timer, \
delayed_work_timer_fn, \
(_tflags) | TIMER_IRQSAFE); \
} while (0)
@@ -258,7 +258,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
#define __INIT_DELAYED_WORK_ONSTACK(_work, _func, _tflags) \
do { \
INIT_WORK_ONSTACK(&(_work)->work, (_func)); \
- __init_timer_on_stack(&(_work)->timer, \
+ __init_timer_work_on_stack(&(_work)->timer, \
delayed_work_timer_fn, \
(_tflags) | TIMER_IRQSAFE); \
} while (0)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 1d17552b3ede..3c47652aeccf 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -691,7 +691,11 @@ static bool timer_fixup_init(void *addr, enum debug_obj_state state)
switch (state) {
case ODEBUG_STATE_ACTIVE:
- del_timer_sync(timer);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_ENABLED;
+ del_timer_shutdown(timer);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_DISABLED;
debug_object_init(timer, &timer_debug_descr);
return true;
default:
@@ -737,8 +741,10 @@ static bool timer_fixup_free(void *addr, enum debug_obj_state state)
switch (state) {
case ODEBUG_STATE_ACTIVE:
- del_timer_sync(timer);
+ del_timer_shutdown(timer);
debug_object_free(timer, &timer_debug_descr);
+ if (timer->enabled != TIMER_DEBUG_WORK)
+ timer->enabled = TIMER_DEBUG_DISABLED;
return true;
default:
return false;
@@ -774,22 +780,37 @@ static const struct debug_obj_descr timer_debug_descr = {
static inline void debug_timer_init(struct timer_list *timer)
{
- if (!timer->enabled)
- debug_object_init(timer, &timer_debug_descr);
+ if (timer->enabled == TIMER_DEBUG_ENABLED)
+ return;
+
+ debug_object_init(timer, &timer_debug_descr);
}
static inline void debug_timer_activate(struct timer_list *timer)
{
- if (!timer->enabled) {
- timer->enabled = 1;
- debug_object_activate(timer, &timer_debug_descr);
- }
+ if (timer->enabled == TIMER_DEBUG_ENABLED)
+ return;
+
+ if (timer->enabled == TIMER_DEBUG_DISABLED)
+ timer->enabled = TIMER_DEBUG_ENABLED;
+
+ debug_object_activate(timer, &timer_debug_descr);
}
-static inline void debug_timer_deactivate(struct timer_list *timer)
+static inline void debug_timer_deactivate(struct timer_list *timer, bool free)
{
- if (timer->enabled)
- debug_object_deactivate(timer, &timer_debug_descr);
+ switch (timer->enabled) {
+ case TIMER_DEBUG_DISABLED:
+ return;
+ case TIMER_DEBUG_ENABLED:
+ if (!free)
+ return;
+ timer->enabled = TIMER_DEBUG_DISABLED;
+ break;
+ case TIMER_DEBUG_WORK:
+ break;
+ }
+ debug_object_deactivate(timer, &timer_debug_descr);
}
static inline void debug_timer_assert_init(struct timer_list *timer)
@@ -833,6 +854,7 @@ static inline void debug_init(struct timer_list *timer)
static inline void debug_deactivate(struct timer_list *timer)
{
+ debug_timer_deactivate(timer, false);
trace_timer_cancel(timer);
}
@@ -1255,7 +1277,7 @@ EXPORT_SYMBOL_GPL(add_timer_on);
* (ie. del_timer() of an inactive timer returns 0, del_timer() of an
* active timer returns 1.)
*/
-int del_timer(struct timer_list *timer)
+int __del_timer(struct timer_list *timer, bool free)
{
struct timer_base *base;
unsigned long flags;
@@ -1266,12 +1288,16 @@ int del_timer(struct timer_list *timer)
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
ret = detach_if_pending(timer, base, true);
+ if (free) {
+ timer->function = NULL;
+ debug_timer_deactivate(timer);
+ }
raw_spin_unlock_irqrestore(&base->lock, flags);
}
return ret;
}
-EXPORT_SYMBOL(del_timer);
+EXPORT_SYMBOL(__del_timer);
static int __try_to_del_timer_sync(struct timer_list *timer, bool free)
{
@@ -1287,7 +1313,7 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool free)
ret = detach_if_pending(timer, base, true);
if (free) {
timer->function = NULL;
- debug_timer_deactivate(timer);
+ debug_timer_deactivate(timer, true);
}
raw_spin_unlock_irqrestore(&base->lock, flags);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 47a7124bbea4..9a48213fc4e4 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1225,6 +1225,16 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, unsigned long work_
put_pwq(pwq);
}
+static void deactivate_timer(struct work_struct *work, bool is_dwork)
+{
+ struct delayed_work *dwork;
+
+ if (!is_dwork)
+ return;
+
+ dwork = to_delayed_work(work);
+}
+
/**
* try_to_grab_pending - steal work item from worklist and disable irq
* @work: work item to steal
@@ -3148,6 +3158,8 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
}
} while (unlikely(ret < 0));
+ deactivate_timer(work, is_dwork);
+
/* tell other tasks trying to grab @work to back off */
mark_work_canceling(work);
local_irq_restore(flags);
diff --git a/net/core/sock.c b/net/core/sock.c
index 10cc84379d75..23a97442a0a6 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3345,7 +3345,7 @@ EXPORT_SYMBOL(sk_reset_timer);
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
- if (del_timer(timer))
+ if (del_timer_try_shutdown(timer))
__sock_put(sk);
}
EXPORT_SYMBOL(sk_stop_timer);
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 19:59 ` Guenter Roeck
@ 2022-10-28 20:40 ` Steven Rostedt
2022-10-28 23:25 ` Guenter Roeck
2022-10-29 14:52 ` Guenter Roeck
1 sibling, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 20:40 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Fri, 28 Oct 2022 12:59:59 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
>
> I'll test again with the following changes on top of your published
> patch series. I hope this is the current status, but I may have lost
> something.
>
> Looking into it ... deactivate_timer() doesn't do anything
> and seems wrong. Did I miss something ?
You mean debug_deactivate_timer() or debug_deactivate?
> --- a/kernel/time/timer.c
> +++ b/kernel/time/timer.c
>
> -static inline void debug_timer_deactivate(struct timer_list *timer)
> +static inline void debug_timer_deactivate(struct timer_list *timer, bool free)
> {
> - if (timer->enabled)
> - debug_object_deactivate(timer, &timer_debug_descr);
> + switch (timer->enabled) {
> + case TIMER_DEBUG_DISABLED:
DISABLE is set before an activate happens (before it is ever armed).
> + return;
> + case TIMER_DEBUG_ENABLED:
> + if (!free)
> + return;
This is called by del_timer{,_sync}() where free is false, or
del_timer_shutdown() where free is true.
We only want to deactivate when free is true.
> + timer->enabled = TIMER_DEBUG_DISABLED;
And we allow for initialization of a "freed" timer again.
> + break;
> + case TIMER_DEBUG_WORK:
This is part of the delayed_work timers, were we keep the old behavior
(del_timer() and del_timer_sync() both deactivate the timer.
> + break;
> + }
> + debug_object_deactivate(timer, &timer_debug_descr);
Here we call the debug object code to deactivate it.
> }
>
> static inline void debug_timer_assert_init(struct timer_list *timer)
> @@ -833,6 +854,7 @@ static inline void debug_init(struct timer_list *timer)
>
> static inline void debug_deactivate(struct timer_list *timer)
> {
> + debug_timer_deactivate(timer, false);
This calls the above code.
> trace_timer_cancel(timer);
> }
Or am I confused and you meant something else?
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-27 22:35 ` Steven Rostedt
@ 2022-10-28 22:31 ` Steven Rostedt
2022-10-28 22:46 ` Jakub Kicinski
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 22:31 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Stephen Boyd, Guenter Roeck,
Jesse Brandeburg, Tony Nguyen, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
Could someone from networking confirm (or deny) that the timer being
removed in sk_stop_timer() will no longer be used even if del_timer()
returns false?
net/core/sock.c:
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
if (del_timer(timer))
__sock_put(sk);
}
If this is the case, then I'll add the following interface:
del_timer_sync_shutdown() // the common case which syncs
del_timer_shutdown() // the uncommon case, that returns immediately
// used for those cases that add extra code to
// handle it, like sk_stop_timer()
Which has the same semantics as del_timer_sync() and del_timer()
respectively, but will prevent the timer from being rearmed again.
This way we can convert the sk_stop_timer() to:
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
if (del_timer_shutdown(timer))
__sock_put(sk);
}
We can also add the del_timer_shutdown() to other locations that need to
put a timer into a shutdown state before freeing, and where it's in a
context that can not call del_timer_sync_shutdown().
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-28 22:31 ` Steven Rostedt
@ 2022-10-28 22:46 ` Jakub Kicinski
2022-10-30 17:22 ` Paolo Abeni
0 siblings, 1 reply; 37+ messages in thread
From: Jakub Kicinski @ 2022-10-28 22:46 UTC (permalink / raw)
To: Steven Rostedt
Cc: Linus Torvalds, linux-kernel, Thomas Gleixner, Stephen Boyd,
Guenter Roeck, Jesse Brandeburg, Tony Nguyen, David S. Miller,
Eric Dumazet, Paolo Abeni, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Fri, 28 Oct 2022 18:31:49 -0400 Steven Rostedt wrote:
> Could someone from networking confirm (or deny) that the timer being
> removed in sk_stop_timer() will no longer be used even if del_timer()
> returns false?
>
> net/core/sock.c:
>
> void sk_stop_timer(struct sock *sk, struct timer_list* timer)
> {
> if (del_timer(timer))
> __sock_put(sk);
> }
>
> If this is the case, then I'll add the following interface:
>
> del_timer_sync_shutdown() // the common case which syncs
>
> del_timer_shutdown() // the uncommon case, that returns immediately
> // used for those cases that add extra code to
> // handle it, like sk_stop_timer()
Sorry too many bugs at once :)
FWIW Paolo was saying privately earlier today that he spotted some cases
of reuse, he gave an example of ccid2_hc_tx_packet_recv()
So we can't convert all cases of sk_stop_timer() in one fell swoop :(
> Which has the same semantics as del_timer_sync() and del_timer()
> respectively, but will prevent the timer from being rearmed again.
>
> This way we can convert the sk_stop_timer() to:
>
> void sk_stop_timer(struct sock *sk, struct timer_list* timer)
> {
> if (del_timer_shutdown(timer))
> __sock_put(sk);
> }
>
>
> We can also add the del_timer_shutdown() to other locations that need to
> put a timer into a shutdown state before freeing, and where it's in a
> context that can not call del_timer_sync_shutdown().
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 20:40 ` Steven Rostedt
@ 2022-10-28 23:25 ` Guenter Roeck
2022-10-28 23:29 ` Steven Rostedt
0 siblings, 1 reply; 37+ messages in thread
From: Guenter Roeck @ 2022-10-28 23:25 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On 10/28/22 13:40, Steven Rostedt wrote:
> On Fri, 28 Oct 2022 12:59:59 -0700
> Guenter Roeck <linux@roeck-us.net> wrote:
>>
>> I'll test again with the following changes on top of your published
>> patch series. I hope this is the current status, but I may have lost
>> something.
>>
>> Looking into it ... deactivate_timer() doesn't do anything
>> and seems wrong. Did I miss something ?
>
> You mean debug_deactivate_timer() or debug_deactivate?
>
This:
+static void deactivate_timer(struct work_struct *work, bool is_dwork)
+{
+ struct delayed_work *dwork;
+
+ if (!is_dwork)
+ return;
+
+ dwork = to_delayed_work(work);
+}
Guenter
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 23:25 ` Guenter Roeck
@ 2022-10-28 23:29 ` Steven Rostedt
0 siblings, 0 replies; 37+ messages in thread
From: Steven Rostedt @ 2022-10-28 23:29 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Fri, 28 Oct 2022 16:25:32 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
> On 10/28/22 13:40, Steven Rostedt wrote:
> > On Fri, 28 Oct 2022 12:59:59 -0700
> > Guenter Roeck <linux@roeck-us.net> wrote:
> >>
> >> I'll test again with the following changes on top of your published
> >> patch series. I hope this is the current status, but I may have lost
> >> something.
> >>
> >> Looking into it ... deactivate_timer() doesn't do anything
> >> and seems wrong. Did I miss something ?
> >
> > You mean debug_deactivate_timer() or debug_deactivate?
> >
>
> This:
>
> +static void deactivate_timer(struct work_struct *work, bool is_dwork)
> +{
> + struct delayed_work *dwork;
> +
> + if (!is_dwork)
> + return;
> +
> + dwork = to_delayed_work(work);
> +}
Oh, that was part of my trying to figure out WTF delayed work was doing
with its timers. You can delete it's existence.
Thanks (and I'll go remove it from my tree).
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-28 19:59 ` Guenter Roeck
2022-10-28 20:40 ` Steven Rostedt
@ 2022-10-29 14:52 ` Guenter Roeck
2022-10-29 19:19 ` Steven Rostedt
1 sibling, 1 reply; 37+ messages in thread
From: Guenter Roeck @ 2022-10-29 14:52 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Fri, Oct 28, 2022 at 01:00:02PM -0700, Guenter Roeck wrote:
> On Fri, Oct 28, 2022 at 02:10:07PM -0400, Steven Rostedt wrote:
> > On Fri, 28 Oct 2022 14:01:29 -0400
> > Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > > @@ -813,6 +839,14 @@ void destroy_timer_on_stack(struct timer_list *timer)
> > > }
> > > EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
> > >
> > > +static struct timer_base *lock_timer_base(struct timer_list *timer,
> > > + unsigned long *flags);
> > > +
> > > +void __timer_reinit_debug_objects(struct timer_list *timer)
> > > +{
> > > + return;
> > > +}
> > > +
> > > #else
> > > static inline void debug_timer_init(struct timer_list *timer) { }
> > > static inline void debug_timer_activate(struct timer_list *timer) { }
> >
> > Bah, the above chunk was leftover from some debugging.
> >
>
> I'll test again with the following changes on top of your published
> patch series. I hope this is the current status, but I may have lost
> something.
>
With the diffs I sent earlier applied, the warning still seen is
WARNING: CPU: 0 PID: 9 at lib/debugobjects.c:502 debug_print_object+0xd0/0x100
ODEBUG: free active (active state 0) object type: timer_list hint: neigh_timer_handler+0x0/0x480
That happens with almost every test, so I may have missed some others
in the noise.
Guenter
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-29 14:52 ` Guenter Roeck
@ 2022-10-29 19:19 ` Steven Rostedt
2022-10-29 22:56 ` Guenter Roeck
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-29 19:19 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Sat, 29 Oct 2022 07:52:41 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
> With the diffs I sent earlier applied, the warning still seen is
>
> WARNING: CPU: 0 PID: 9 at lib/debugobjects.c:502 debug_print_object+0xd0/0x100
> ODEBUG: free active (active state 0) object type: timer_list hint: neigh_timer_handler+0x0/0x480
>
> That happens with almost every test, so I may have missed some others
> in the noise.
Can you add this?
-- Steve
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 3c4786b99907..3e2586c72c7e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -895,6 +895,8 @@ void neigh_destroy(struct neighbour *neigh)
if (neigh_del_timer(neigh))
pr_warn("Impossible event\n");
+ del_timer_try_shutdown(&neigh->timer);
+
write_lock_bh(&neigh->lock);
__skb_queue_purge(&neigh->arp_queue);
write_unlock_bh(&neigh->lock);
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-29 19:19 ` Steven Rostedt
@ 2022-10-29 22:56 ` Guenter Roeck
2022-10-30 15:48 ` Steven Rostedt
0 siblings, 1 reply; 37+ messages in thread
From: Guenter Roeck @ 2022-10-29 22:56 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On 10/29/22 12:19, Steven Rostedt wrote:
> On Sat, 29 Oct 2022 07:52:41 -0700
> Guenter Roeck <linux@roeck-us.net> wrote:
>
>> With the diffs I sent earlier applied, the warning still seen is
>>
>> WARNING: CPU: 0 PID: 9 at lib/debugobjects.c:502 debug_print_object+0xd0/0x100
>> ODEBUG: free active (active state 0) object type: timer_list hint: neigh_timer_handler+0x0/0x480
>>
>> That happens with almost every test, so I may have missed some others
>> in the noise.
>
> Can you add this?
>
It doesn't make a difference.
Guenter
> -- Steve
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 3c4786b99907..3e2586c72c7e 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -895,6 +895,8 @@ void neigh_destroy(struct neighbour *neigh)
> if (neigh_del_timer(neigh))
> pr_warn("Impossible event\n");
>
> + del_timer_try_shutdown(&neigh->timer);
> +
> write_lock_bh(&neigh->lock);
> __skb_queue_purge(&neigh->arp_queue);
> write_unlock_bh(&neigh->lock);
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-29 22:56 ` Guenter Roeck
@ 2022-10-30 15:48 ` Steven Rostedt
2022-10-31 15:50 ` Guenter Roeck
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-10-30 15:48 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Sat, 29 Oct 2022 15:56:25 -0700
Guenter Roeck <linux@roeck-us.net> wrote:
> >> WARNING: CPU: 0 PID: 9 at lib/debugobjects.c:502 debug_print_object+0xd0/0x100
> >> ODEBUG: free active (active state 0) object type: timer_list hint: neigh_timer_handler+0x0/0x480
> >>
> >> That happens with almost every test, so I may have missed some others
> >> in the noise.
> >
> > Can you add this?
> >
>
> It doesn't make a difference.
Ah, it also requires this (I have other debugging in that file, so it may
only apply with some fuzzing):
-- Steve
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index ac2e8beb4235..f2ccf24a8448 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1282,6 +1296,11 @@ int __del_timer(struct timer_list *timer, bool free)
debug_timer_deactivate(timer, true);
}
raw_spin_unlock_irqrestore(&base->lock, flags);
+ } else if (free) {
+ base = lock_timer_base(timer, &flags);
+ timer->function = NULL;
+ debug_timer_deactivate(timer, true);
+ raw_spin_unlock_irqrestore(&base->lock, flags);
}
return ret;
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-28 22:46 ` Jakub Kicinski
@ 2022-10-30 17:22 ` Paolo Abeni
2022-11-03 21:51 ` Steven Rostedt
0 siblings, 1 reply; 37+ messages in thread
From: Paolo Abeni @ 2022-10-30 17:22 UTC (permalink / raw)
To: Jakub Kicinski, Steven Rostedt
Cc: Linus Torvalds, linux-kernel, Thomas Gleixner, Stephen Boyd,
Guenter Roeck, Jesse Brandeburg, Tony Nguyen, David S. Miller,
Eric Dumazet, Mirko Lindner, Stephen Hemminger, Martin KaFai Lau,
Alexei Starovoitov, Kuniyuki Iwashima, Pavel Begunkov,
Menglong Dong, linux-usb, linux-wireless, bridge, netfilter-devel,
coreteam, lvs-devel, linux-afs, linux-nfs, tipc-discussion
On Fri, 2022-10-28 at 15:46 -0700, Jakub Kicinski wrote:
> On Fri, 28 Oct 2022 18:31:49 -0400 Steven Rostedt wrote:
> > Could someone from networking confirm (or deny) that the timer being
> > removed in sk_stop_timer() will no longer be used even if del_timer()
> > returns false?
> >
> > net/core/sock.c:
> >
> > void sk_stop_timer(struct sock *sk, struct timer_list* timer)
> > {
> > if (del_timer(timer))
> > __sock_put(sk);
> > }
> >
> > If this is the case, then I'll add the following interface:
> >
> > del_timer_sync_shutdown() // the common case which syncs
> >
> > del_timer_shutdown() // the uncommon case, that returns immediately
> > // used for those cases that add extra code to
> > // handle it, like sk_stop_timer()
>
> Sorry too many bugs at once :)
>
> FWIW Paolo was saying privately earlier today that he spotted some cases
> of reuse, he gave an example of ccid2_hc_tx_packet_recv()
For the records, there are other cases, e.g. after sk_stop_timer() in
clear_3rdack_retransmission() (mptcp code) the timer can be-rearmed
without re-initializing. I *think* there are more of such use in the
in ax25/rose code.
> So we can't convert all cases of sk_stop_timer() in one fell swoop :(
On the positive side, I think converting the sk_stop_timer in
inet_csk_clear_xmit_timers() should be safe and should cover the issue
reported by Guenter
Cheers,
Paolo
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-30 15:48 ` Steven Rostedt
@ 2022-10-31 15:50 ` Guenter Roeck
2022-10-31 20:14 ` Guenter Roeck
0 siblings, 1 reply; 37+ messages in thread
From: Guenter Roeck @ 2022-10-31 15:50 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Sun, Oct 30, 2022 at 11:48:28AM -0400, Steven Rostedt wrote:
> On Sat, 29 Oct 2022 15:56:25 -0700
> Guenter Roeck <linux@roeck-us.net> wrote:
>
> > >> WARNING: CPU: 0 PID: 9 at lib/debugobjects.c:502 debug_print_object+0xd0/0x100
> > >> ODEBUG: free active (active state 0) object type: timer_list hint: neigh_timer_handler+0x0/0x480
> > >>
> > >> That happens with almost every test, so I may have missed some others
> > >> in the noise.
> > >
> > > Can you add this?
> > >
> >
> > It doesn't make a difference.
>
> Ah, it also requires this (I have other debugging in that file, so it may
> only apply with some fuzzing):
>
Almost good, except for the attached backtrace. That seems to happen
on shutdown after bootting from a usb drive, but not on all platforms.
The warning is in __mod_timer():
if (WARN_ON_ONCE(!timer->function))
return -EINVAL;
This may be due to the change in blk_sync_queue() which I suspect may
be called prior to the last mod_timer() call. I'll add some debug code
to verify.
Guenter
------------[ cut here ]------------
WARNING: CPU: 0 PID: 283 at kernel/time/timer.c:1046 mod_timer+0x294/0x34c
Modules linked in:
CPU: 0 PID: 283 Comm: init Tainted: G N 6.1.0-rc2-00397-g18ccc9f8a778 #1
Hardware name: Freescale i.MX25 (Device Tree Support)
unwind_backtrace from show_stack+0x10/0x18
show_stack from dump_stack_lvl+0x34/0x54
dump_stack_lvl from __warn+0xc0/0x1f0
__warn from warn_slowpath_fmt+0x5c/0xc4
warn_slowpath_fmt from mod_timer+0x294/0x34c
mod_timer from blk_add_timer+0xa4/0xb4
blk_add_timer from blk_mq_start_request+0x84/0x1f4
blk_mq_start_request from scsi_queue_rq+0x4a8/0xb84
scsi_queue_rq from blk_mq_dispatch_rq_list+0x320/0x9d0
blk_mq_dispatch_rq_list from __blk_mq_sched_dispatch_requests+0xb0/0x158
__blk_mq_sched_dispatch_requests from blk_mq_sched_dispatch_requests+0x34/0x64
blk_mq_sched_dispatch_requests from __blk_mq_run_hw_queue+0x8c/0x234
__blk_mq_run_hw_queue from blk_mq_sched_insert_request+0xe8/0x15c
blk_mq_sched_insert_request from blk_execute_rq+0xa4/0x1d0
blk_execute_rq from __scsi_execute+0xb4/0x19c
__scsi_execute from sd_sync_cache+0xac/0x1ec
sd_sync_cache from sd_shutdown+0x5c/0xc8
sd_shutdown from sd_remove+0x30/0x44
sd_remove from device_release_driver_internal+0xd0/0x16c
device_release_driver_internal from bus_remove_device+0xd0/0x100
bus_remove_device from device_del+0x190/0x464
device_del from __scsi_remove_device+0x130/0x184
__scsi_remove_device from scsi_forget_host+0x60/0x64
scsi_forget_host from scsi_remove_host+0x6c/0x188
scsi_remove_host from usb_stor_disconnect+0x40/0xf4
usb_stor_disconnect from usb_unbind_interface+0x68/0x230
usb_unbind_interface from device_release_driver_internal+0xd0/0x16c
device_release_driver_internal from bus_remove_device+0xd0/0x100
bus_remove_device from device_del+0x190/0x464
device_del from usb_disable_device+0x88/0x130
usb_disable_device from usb_disconnect+0xb4/0x234
usb_disconnect from usb_disconnect+0x9c/0x234
usb_disconnect from usb_remove_hcd+0xd0/0x16c
usb_remove_hcd from host_stop+0x38/0xa8
host_stop from ci_hdrc_remove+0x40/0x11c
ci_hdrc_remove from platform_remove+0x24/0x54
platform_remove from device_release_driver_internal+0xd0/0x16c
device_release_driver_internal from bus_remove_device+0xd0/0x100
bus_remove_device from device_del+0x190/0x464
device_del from platform_device_del.part.0+0x10/0x78
platform_device_del.part.0 from platform_device_unregister+0x18/0x28
platform_device_unregister from ci_hdrc_remove_device+0xc/0x24
ci_hdrc_remove_device from ci_hdrc_imx_remove+0x28/0xfc
ci_hdrc_imx_remove from device_shutdown+0x178/0x230
device_shutdown from kernel_restart_prepare+0x2c/0x3c
kernel_restart_prepare from kernel_restart+0xc/0x68
kernel_restart from __do_sys_reboot+0xc0/0x204
__do_sys_reboot from ret_fast_syscall+0x0/0x1c
Exception stack(0xc8ca1fa8 to 0xc8ca1ff0)
1fa0: 01234567 0000000f fee1dead 28121969 01234567 00000000
1fc0: 01234567 0000000f 00000001 00000058 000e05c0 00000000 00000000 00000000
1fe0: 000e0298 bea82de4 000994bc b6f6d2c0
irq event stamp: 3443
hardirqs last enabled at (3451): [<c0074590>] __up_console_sem+0x64/0x88
hardirqs last disabled at (3458): [<c007457c>] __up_console_sem+0x50/0x88
softirqs last enabled at (3438): [<c000988c>] __do_softirq+0x2fc/0x5d0
softirqs last disabled at (3433): [<c0022518>] __irq_exit_rcu+0x170/0x1ec
---[ end trace 0000000000000000 ]---
sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=0x01 driverbyte=DRIVER_OK
ci_hdrc ci_hdrc.0: USB bus 1 deregistered
reboot: Restarting system
------------
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 20/31] timers: usb: Use del_timer_shutdown() before freeing timer
2022-10-31 15:50 ` Guenter Roeck
@ 2022-10-31 20:14 ` Guenter Roeck
0 siblings, 0 replies; 37+ messages in thread
From: Guenter Roeck @ 2022-10-31 20:14 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Linus Torvalds, Thomas Gleixner, Stephen Boyd,
Greg Kroah-Hartman, Felipe Balbi, Johan Hovold, Alan Stern,
Mathias Nyman, Kai-Heng Feng, Matthias Kaehlcke,
Michael Grzeschik, Bhuvanesh Surachari, Dan Carpenter, linux-usb,
Tejun Heo, Lai Jiangshan, John Stultz
On Mon, Oct 31, 2022 at 08:50:58AM -0700, Guenter Roeck wrote:
> On Sun, Oct 30, 2022 at 11:48:28AM -0400, Steven Rostedt wrote:
> > On Sat, 29 Oct 2022 15:56:25 -0700
> > Guenter Roeck <linux@roeck-us.net> wrote:
> >
> > > >> WARNING: CPU: 0 PID: 9 at lib/debugobjects.c:502 debug_print_object+0xd0/0x100
> > > >> ODEBUG: free active (active state 0) object type: timer_list hint: neigh_timer_handler+0x0/0x480
> > > >>
> > > >> That happens with almost every test, so I may have missed some others
> > > >> in the noise.
> > > >
> > > > Can you add this?
> > > >
> > >
> > > It doesn't make a difference.
> >
> > Ah, it also requires this (I have other debugging in that file, so it may
> > only apply with some fuzzing):
> >
>
> Almost good, except for the attached backtrace. That seems to happen
> on shutdown after bootting from a usb drive, but not on all platforms.
>
> The warning is in __mod_timer():
>
> if (WARN_ON_ONCE(!timer->function))
> return -EINVAL;
>
> This may be due to the change in blk_sync_queue() which I suspect may
> be called prior to the last mod_timer() call. I'll add some debug code
> to verify.
>
I see that additional requests are sent to the scsi device after the call
to blk_sync_queue(). The description of this function suggests that this
may happen. Overall it does not seem to be appropriate to call
del_timer_shutdown() from blk_sync_queue(). I'll change my test code
accordingly.
Guenter
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-10-30 17:22 ` Paolo Abeni
@ 2022-11-03 21:51 ` Steven Rostedt
2022-11-04 0:00 ` Eric Dumazet
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-11-03 21:51 UTC (permalink / raw)
To: Paolo Abeni
Cc: Jakub Kicinski, Linus Torvalds, linux-kernel, Thomas Gleixner,
Stephen Boyd, Guenter Roeck, Jesse Brandeburg, Tony Nguyen,
David S. Miller, Eric Dumazet, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Sun, 30 Oct 2022 18:22:03 +0100
Paolo Abeni <pabeni@redhat.com> wrote:
> On the positive side, I think converting the sk_stop_timer in
> inet_csk_clear_xmit_timers() should be safe and should cover the issue
> reported by Guenter
Would something like this be OK?
[ Note, talking with Thomas Gleixner, we agreed that we are changing the
name to: time_shutdown_sync() and timer_shutdown() (no wait version).
I'll be posting new patches soon. ]
-- Steve
diff --git a/include/net/sock.h b/include/net/sock.h
index 22f8bab583dd..0ef58697d4e5 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2439,6 +2439,8 @@ void sk_stop_timer(struct sock *sk, struct timer_list *timer);
void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer);
+void sk_shutdown_timer(struct sock *sk, struct timer_list *timer);
+
int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
struct sk_buff *skb, unsigned int flags,
void (*destructor)(struct sock *sk,
diff --git a/net/core/sock.c b/net/core/sock.c
index a3ba0358c77c..82124862b594 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3357,6 +3357,13 @@ void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
}
EXPORT_SYMBOL(sk_stop_timer_sync);
+void sk_shutdown_timer(struct sock *sk, struct timer_list* timer)
+{
+ if (timer_shutdown(timer))
+ __sock_put(sk);
+}
+EXPORT_SYMBOL(sk_shutdown_timer);
+
void sock_init_data(struct socket *sock, struct sock *sk)
{
sk_init_common(sk);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 5e70228c5ae9..71f398f51958 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -722,15 +722,15 @@ void inet_csk_clear_xmit_timers(struct sock *sk)
icsk->icsk_pending = icsk->icsk_ack.pending = 0;
- sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
- sk_stop_timer(sk, &icsk->icsk_delack_timer);
- sk_stop_timer(sk, &sk->sk_timer);
+ sk_shutdown_timer(sk, &icsk->icsk_retransmit_timer);
+ sk_shutdown_timer(sk, &icsk->icsk_delack_timer);
+ sk_shutdown_timer(sk, &sk->sk_timer);
}
EXPORT_SYMBOL(inet_csk_clear_xmit_timers);
void inet_csk_delete_keepalive_timer(struct sock *sk)
{
- sk_stop_timer(sk, &sk->sk_timer);
+ sk_shutdown_timer(sk, &sk->sk_timer);
}
EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-11-03 21:51 ` Steven Rostedt
@ 2022-11-04 0:00 ` Eric Dumazet
2022-11-04 5:51 ` Steven Rostedt
0 siblings, 1 reply; 37+ messages in thread
From: Eric Dumazet @ 2022-11-04 0:00 UTC (permalink / raw)
To: Steven Rostedt
Cc: Paolo Abeni, Jakub Kicinski, Linus Torvalds, linux-kernel,
Thomas Gleixner, Stephen Boyd, Guenter Roeck, Jesse Brandeburg,
Tony Nguyen, David S. Miller, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, Nov 3, 2022 at 2:51 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Sun, 30 Oct 2022 18:22:03 +0100
> Paolo Abeni <pabeni@redhat.com> wrote:
>
> > On the positive side, I think converting the sk_stop_timer in
> > inet_csk_clear_xmit_timers() should be safe and should cover the issue
> > reported by Guenter
>
> Would something like this be OK?
>
> [ Note, talking with Thomas Gleixner, we agreed that we are changing the
> name to: time_shutdown_sync() and timer_shutdown() (no wait version).
> I'll be posting new patches soon. ]
>
> -- Steve
>
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 22f8bab583dd..0ef58697d4e5 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -2439,6 +2439,8 @@ void sk_stop_timer(struct sock *sk, struct timer_list *timer);
>
> void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer);
>
> +void sk_shutdown_timer(struct sock *sk, struct timer_list *timer);
> +
> int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
> struct sk_buff *skb, unsigned int flags,
> void (*destructor)(struct sock *sk,
> diff --git a/net/core/sock.c b/net/core/sock.c
> index a3ba0358c77c..82124862b594 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -3357,6 +3357,13 @@ void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
> }
> EXPORT_SYMBOL(sk_stop_timer_sync);
>
> +void sk_shutdown_timer(struct sock *sk, struct timer_list* timer)
> +{
> + if (timer_shutdown(timer))
> + __sock_put(sk);
> +}
> +EXPORT_SYMBOL(sk_shutdown_timer);
> +
> void sock_init_data(struct socket *sock, struct sock *sk)
> {
> sk_init_common(sk);
> diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> index 5e70228c5ae9..71f398f51958 100644
> --- a/net/ipv4/inet_connection_sock.c
> +++ b/net/ipv4/inet_connection_sock.c
> @@ -722,15 +722,15 @@ void inet_csk_clear_xmit_timers(struct sock *sk)
>
> icsk->icsk_pending = icsk->icsk_ack.pending = 0;
>
> - sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
> - sk_stop_timer(sk, &icsk->icsk_delack_timer);
> - sk_stop_timer(sk, &sk->sk_timer);
> + sk_shutdown_timer(sk, &icsk->icsk_retransmit_timer);
> + sk_shutdown_timer(sk, &icsk->icsk_delack_timer);
> + sk_shutdown_timer(sk, &sk->sk_timer);
> }
> EXPORT_SYMBOL(inet_csk_clear_xmit_timers);
inet_csk_clear_xmit_timers() can be called multiple times during TCP
socket lifetime.
(See tcp_disconnect(), which can be followed by another connect() ... and loop)
Maybe add a second parameter, or add a new
inet_csk_shutdown_xmit_timers() only called from tcp_v4_destroy_sock() ?
>
> void inet_csk_delete_keepalive_timer(struct sock *sk)
> {
> - sk_stop_timer(sk, &sk->sk_timer);
> + sk_shutdown_timer(sk, &sk->sk_timer);
SO_KEEPALIVE can be called multiple times in a TCP socket lifetime,
on/off/on/off/...
I suggest leaving sk_stop_timer() here.
Eventually inet_csk_clear_xmit_timers( sk, destroy=true) (or
inet_csk_shutdown_xmit_timers(())
will be called before the socket is destroyed.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-11-04 0:00 ` Eric Dumazet
@ 2022-11-04 5:51 ` Steven Rostedt
2022-11-04 16:14 ` Guenter Roeck
0 siblings, 1 reply; 37+ messages in thread
From: Steven Rostedt @ 2022-11-04 5:51 UTC (permalink / raw)
To: Eric Dumazet
Cc: Paolo Abeni, Jakub Kicinski, Linus Torvalds, linux-kernel,
Thomas Gleixner, Stephen Boyd, Guenter Roeck, Jesse Brandeburg,
Tony Nguyen, David S. Miller, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Thu, 3 Nov 2022 17:00:20 -0700
Eric Dumazet <edumazet@google.com> wrote:
> inet_csk_clear_xmit_timers() can be called multiple times during TCP
> socket lifetime.
>
> (See tcp_disconnect(), which can be followed by another connect() ... and loop)
>
> Maybe add a second parameter, or add a new
> inet_csk_shutdown_xmit_timers() only called from tcp_v4_destroy_sock() ?
>
I guess.
> >
> > void inet_csk_delete_keepalive_timer(struct sock *sk)
> > {
> > - sk_stop_timer(sk, &sk->sk_timer);
> > + sk_shutdown_timer(sk, &sk->sk_timer);
>
> SO_KEEPALIVE can be called multiple times in a TCP socket lifetime,
> on/off/on/off/...
>
> I suggest leaving sk_stop_timer() here.
>
> Eventually inet_csk_clear_xmit_timers( sk, destroy=true) (or
> inet_csk_shutdown_xmit_timers(())
> will be called before the socket is destroyed.
OK.
Guenter,
I posted a new series, but did not include this change. If you want to
test that other series, I would suggest to at least add the first part
of this patch, otherwise it will trigger. But we want to see if there's
other locations of issue that we should care about.
-- Steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer
2022-11-04 5:51 ` Steven Rostedt
@ 2022-11-04 16:14 ` Guenter Roeck
0 siblings, 0 replies; 37+ messages in thread
From: Guenter Roeck @ 2022-11-04 16:14 UTC (permalink / raw)
To: Steven Rostedt
Cc: Eric Dumazet, Paolo Abeni, Jakub Kicinski, Linus Torvalds,
linux-kernel, Thomas Gleixner, Stephen Boyd, Jesse Brandeburg,
Tony Nguyen, David S. Miller, Mirko Lindner, Stephen Hemminger,
Martin KaFai Lau, Alexei Starovoitov, Kuniyuki Iwashima,
Pavel Begunkov, Menglong Dong, linux-usb, linux-wireless, bridge,
netfilter-devel, coreteam, lvs-devel, linux-afs, linux-nfs,
tipc-discussion
On Fri, Nov 04, 2022 at 01:51:39AM -0400, Steven Rostedt wrote:
> On Thu, 3 Nov 2022 17:00:20 -0700
> Eric Dumazet <edumazet@google.com> wrote:
>
> > inet_csk_clear_xmit_timers() can be called multiple times during TCP
> > socket lifetime.
> >
> > (See tcp_disconnect(), which can be followed by another connect() ... and loop)
> >
> > Maybe add a second parameter, or add a new
> > inet_csk_shutdown_xmit_timers() only called from tcp_v4_destroy_sock() ?
> >
>
> I guess.
>
> > >
> > > void inet_csk_delete_keepalive_timer(struct sock *sk)
> > > {
> > > - sk_stop_timer(sk, &sk->sk_timer);
> > > + sk_shutdown_timer(sk, &sk->sk_timer);
> >
> > SO_KEEPALIVE can be called multiple times in a TCP socket lifetime,
> > on/off/on/off/...
> >
> > I suggest leaving sk_stop_timer() here.
> >
> > Eventually inet_csk_clear_xmit_timers( sk, destroy=true) (or
> > inet_csk_shutdown_xmit_timers(())
> > will be called before the socket is destroyed.
>
> OK.
>
> Guenter,
>
> I posted a new series, but did not include this change. If you want to
> test that other series, I would suggest to at least add the first part
> of this patch, otherwise it will trigger. But we want to see if there's
> other locations of issue that we should care about.
>
I'll run a test on the other series without change first. We'll see what
happens. If necessary I'll add [parts of] this patch and re-test, but
before doing that I would like to get a sense for the status of your
series as-is.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2022-11-04 16:15 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20221027150525.753064657@goodmis.org>
2022-10-27 15:05 ` [RFC][PATCH v2 19/31] timers: net: Use del_timer_shutdown() before freeing timer Steven Rostedt
2022-10-27 19:55 ` Steven Rostedt
2022-10-27 20:15 ` Linus Torvalds
2022-10-27 20:34 ` Steven Rostedt
2022-10-27 20:48 ` Linus Torvalds
2022-10-27 21:07 ` Steven Rostedt
2022-10-27 21:15 ` Steven Rostedt
2022-10-27 22:35 ` Steven Rostedt
2022-10-28 22:31 ` Steven Rostedt
2022-10-28 22:46 ` Jakub Kicinski
2022-10-30 17:22 ` Paolo Abeni
2022-11-03 21:51 ` Steven Rostedt
2022-11-04 0:00 ` Eric Dumazet
2022-11-04 5:51 ` Steven Rostedt
2022-11-04 16:14 ` Guenter Roeck
2022-10-27 21:07 ` Steven Rostedt
2022-10-28 15:16 ` Guenter Roeck
2022-10-27 15:05 ` [RFC][PATCH v2 20/31] timers: usb: " Steven Rostedt
2022-10-27 20:38 ` Alan Stern
2022-10-27 20:42 ` Steven Rostedt
2022-10-27 21:22 ` Steven Rostedt
2022-10-28 5:23 ` Guenter Roeck
2022-10-28 10:14 ` Steven Rostedt
2022-10-28 14:00 ` Steven Rostedt
2022-10-28 18:01 ` Steven Rostedt
2022-10-28 18:10 ` Steven Rostedt
2022-10-28 19:59 ` Guenter Roeck
2022-10-28 20:40 ` Steven Rostedt
2022-10-28 23:25 ` Guenter Roeck
2022-10-28 23:29 ` Steven Rostedt
2022-10-29 14:52 ` Guenter Roeck
2022-10-29 19:19 ` Steven Rostedt
2022-10-29 22:56 ` Guenter Roeck
2022-10-30 15:48 ` Steven Rostedt
2022-10-31 15:50 ` Guenter Roeck
2022-10-31 20:14 ` Guenter Roeck
[not found] ` <20221028021815.3130-1-hdanton@sina.com>
2022-10-28 3:17 ` Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).