5.18.3-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 812/879 thermal: devfreq_cooling: use local ops instead of global ops
In reply to Greg Kroah-HartmanFrom: Kant Fan <[email protected]>
commit b947769b8f778db130aad834257fcaca25df2edc upstream.
Fix access illegal address problem in following condition:
There are multiple devfreq cooling devices in system, some of them has EM model but others do not. Energy model ops such as state2power will append to global devfreq_cooling_ops when the cooling device with EM model is registered. It makes the cooling device without EM model also use devfreq_cooling_ops after appending when registered later by of_devfreq_cooling_register_power() or of_devfreq_cooling_register().
The IPA governor regards the cooling devices without EM model as a power actor, because they also have energy model ops, and will access illegal address at dfc->em_pd when execute cdev->ops->get_requested_power, cdev->ops->state2power or cdev->ops->power2state.
--- drivers/thermal/devfreq_cooling.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/thermal/devfreq_cooling.c +18 -7
@@ -358,21 +358,28 @@ of_devfreq_cooling_register_power(structstruct thermal_cooling_device *cdev;struct device *dev = df->dev.parent;struct devfreq_cooling_device *dfc; +struct thermal_cooling_device_ops *ops;char *name;int err, num_opps; - dfc =kzalloc (sizeof (*dfc),GFP_KERNEL ); -if (!dfc) + ops =kmemdup (&devfreq_cooling_ops,sizeof (*ops),GFP_KERNEL ); +if (!ops)return ERR_PTR (-ENOMEM ); + dfc =kzalloc (sizeof (*dfc),GFP_KERNEL ); +if (!dfc) { + err = -ENOMEM ; + goto free_ops; + } + dfc->devfreq = df; dfc->em_pd =em_pd_get (dev);if (dfc->em_pd) { - devfreq_cooling_ops.get_requested_power = + ops->get_requested_power = devfreq_cooling_get_requested_power; - devfreq_cooling_ops.state2power = devfreq_cooling_state2power; - devfreq_cooling_ops.power2state = devfreq_cooling_power2state; + ops->state2power = devfreq_cooling_state2power; + ops->power2state = devfreq_cooling_power2state; dfc->power_ops = dfc_power;
@@ -407,8 +414,7 @@ of_devfreq_cooling_register_power(structif (!name) goto remove_qos_req; - cdev =thermal_of_cooling_device_register (np, name, dfc, - &devfreq_cooling_ops); + cdev =thermal_of_cooling_device_register (np, name, dfc, ops);kfree (name);if (IS_ERR (cdev)) {
@@ -429,6 +435,8 @@ free_table:kfree (dfc->freq_table); free_dfc:kfree (dfc); +free_ops: +kfree (ops);return ERR_PTR (err); }
@@ -510,11 +518,13 @@ EXPORT_SYMBOL_GPL(devfreq_cooling_em_regvoid devfreq_cooling_unregister (struct thermal_cooling_device *cdev) {struct devfreq_cooling_device *dfc; +const struct thermal_cooling_device_ops *ops;struct device *dev;if (IS_ERR_OR_NULL (cdev))return ; + ops = cdev->ops; dfc = cdev->devdata; dev = dfc->devfreq->dev.parent;
@@ -525,5 +535,6 @@ void devfreq_cooling_unregister(struct tkfree (dfc->freq_table);kfree (dfc); +kfree (ops); }EXPORT_SYMBOL_GPL (devfreq_cooling_unregister);
Greg Kroah-Hartman
maintainerPATCH 813/879 mt76: fix use-after-free by removing a non-RCU wcid pointer
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit 51fb1278aa57ae0fc54adaa786e1965362bed4fb upstream.
Fixes an issue caught by KASAN about use-after-free in mt76_txq_schedule by protecting mtxq->wcid with rcu_lock between mt76_txq_schedule and sta_info_[alloc, free].
[18853.876689] ================================================================== [18853.876751] BUG: KASAN: use-after-free in mt76_txq_schedule+0x204/0xaf8 [mt76] [18853.876773] Read of size 8 at addr ffffffaf989a2138 by task mt76-tx phy0/883 [18853.876786] [18853.876810] CPU: 5 PID: 883 Comm: mt76-tx phy0 Not tainted 5.10.100-fix-510-56778d365941-kasan #5 0b01fbbcf41a530f52043508fec2e31a4215
[18853.876840] Call trace: [18853.876861] dump_backtrace+0x0/0x3ec [18853.876878] show_stack+0x20/0x2c [18853.876899] dump_stack+0x11c/0x1ac [18853.876918] print_address_description+0x74/0x514 [18853.876934] kasan_report+0x134/0x174 [18853.876948] __asan_report_load8_noabort+0x44/0x50 [18853.876976] mt76_txq_schedule+0x204/0xaf8 [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877002] mt76_txq_schedule_all+0x2c/0x48 [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877030] mt7921_tx_worker+0xa0/0x1cc [mt7921_common f0875ebac9d7b4754e1010549e7db50fbd90a047] [18853.877054] __mt76_worker_fn+0x190/0x22c [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877071] kthread+0x2f8/0x3b8 [18853.877087] ret_from_fork+0x10/0x30 [18853.877098] [18853.877112] Allocated by task 941: [18853.877131] kasan_save_stack+0x38/0x68 [18853.877147] __kasan_kmalloc+0xd4/0xfc [18853.877163] kasan_kmalloc+0x10/0x1c [18853.877177] __kmalloc+0x264/0x3c4 [18853.877294] sta_info_alloc+0x460/0xf88 [mac80211] [18853.877410] ieee80211_prep_connection+0x204/0x1ee0 [mac80211] [18853.877523] ieee80211_mgd_auth+0x6c4/0xa4c [mac80211] [18853.877635] ieee80211_auth+0x20/0x2c [mac80211] [18853.877733] rdev_auth+0x7c/0x438 [cfg80211] [18853.877826] cfg80211_mlme_auth+0x26c/0x390 [cfg80211] [18853.877919] nl80211_authenticate+0x6d4/0x904 [cfg80211] [18853.877938] genl_rcv_msg+0x748/0x93c [18853.877954] netlink_rcv_skb+0x160/0x2a8 [18853.877969] genl_rcv+0x3c/0x54 [18853.877985] netlink_unicast_kernel+0x104/0x1ec [18853.877999] netlink_unicast+0x178/0x268 [18853.878015] netlink_sendmsg+0x3cc/0x5f0 [18853.878030] sock_sendmsg+0xb4/0xd8 [18853.878043] ____sys_sendmsg+0x2f8/0x53c [18853.878058] ___sys_sendmsg+0xe8/0x150 [18853.878071] __sys_sendmsg+0xc4/0x1f4 [18853.878087] __arm64_compat_sys_sendmsg+0x88/0x9c [18853.878101] el0_svc_common+0x1b4/0x390 [18853.878115] do_el0_svc_compat+0x8c/0xdc [18853.878131] el0_svc_compat+0x10/0x1c [18853.878146] el0_sync_compat_handler+0xa8/0xcc [18853.878161] el0_sync_compat+0x188/0x1c0 [18853.878171] [18853.878183] Freed by task 10927: [18853.878200] kasan_save_stack+0x38/0x68 [18853.878215] kasan_set_track+0x28/0x3c [18853.878228] kasan_set_free_info+0x24/0x48 [18853.878244] __kasan_slab_free+0x11c/0x154 [18853.878259] kasan_slab_free+0x14/0x24 [18853.878273] slab_free_freelist_hook+0xac/0x1b0 [18853.878287] kfree+0x104/0x390 [18853.878402] sta_info_free+0x198/0x210 [mac80211] [18853.878515] __sta_info_destroy_part2+0x230/0x2d4 [mac80211] [18853.878628] __sta_info_flush+0x300/0x37c [mac80211] [18853.878740] ieee80211_set_disassoc+0x2cc/0xa7c [mac80211] [18853.878851] ieee80211_mgd_deauth+0x4a4/0x10a0 [mac80211] [18853.878962] ieee80211_deauth+0x20/0x2c [mac80211] [18853.879057] rdev_deauth+0x7c/0x438 [cfg80211] [18853.879150] cfg80211_mlme_deauth+0x274/0x414 [cfg80211] [18853.879243] cfg80211_mlme_down+0xe4/0x118 [cfg80211] [18853.879335] cfg80211_disconnect+0x218/0x2d8 [cfg80211] [18853.879427] __cfg80211_leave+0x17c/0x240 [cfg80211] [18853.879519] cfg80211_leave+0x3c/0x58 [cfg80211] [18853.879611] wiphy_suspend+0xdc/0x200 [cfg80211] [18853.879628] dpm_run_callback+0x58/0x408 [18853.879642] __device_suspend+0x4cc/0x864 [18853.879658] async_suspend+0x34/0xf4 [18853.879673] async_run_entry_fn+0xe0/0x37c [18853.879689] process_one_work+0x508/0xb98 [18853.879702] worker_thread+0x7f4/0xcd4 [18853.879717] kthread+0x2f8/0x3b8 [18853.879731] ret_from_fork+0x10/0x30 [18853.879741] [18853.879757] The buggy address belongs to the object at ffffffaf989a2000 [18853.879757] which belongs to the cache kmalloc-8k of size 8192 [18853.879774] The buggy address is located 312 bytes inside of [18853.879774] 8192-byte region [ffffffaf989a2000, ffffffaf989a4000) [18853.879787] The buggy address belongs to the page: [18853.879807] page:000000004bda2a59 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1d89a0 [18853.879823] head:000000004bda2a59 order:3 compound_mapcount:0 compound_pincount:0 [18853.879839] flags: 0x8000000000010200(slab|head) [18853.879857] raw: 8000000000010200 ffffffffbc89e208 ffffffffb7fb5208 ffffffaec000cc80 [18853.879873] raw: 0000000000000000 0000000000010001 00000001ffffffff 0000000000000000 [18853.879885] page dumped because: kasan: bad access detected [18853.879896] [18853.879907] Memory state around the buggy address: [18853.879922] ffffffaf989a2000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879935] ffffffaf989a2080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879948] >ffffffaf989a2100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879961] ^ [18853.879973] ffffffaf989a2180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879986] ffffffaf989a2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879998] ==================================================================
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 +++- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 9 ++++----- 8 files changed, 13 insertions(+), 12 deletions(-)
drivers/net/wireless/mediatek/mt76/mac80211.c +1 -1
@@ -1303,7 +1303,7 @@ mt76_sta_add(struct mt76_dev *dev, struccontinue ; mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv; - mtxq->wcid = wcid; + mtxq->wcid = wcid->idx; }ewma_signal_init (&wcid->rssi);
drivers/net/wireless/mediatek/mt76/mt76.h +1 -1
@@ -275,7 +275,7 @@ struct mt76_wcid { };struct mt76_txq { -struct mt76_wcid *wcid; +u16 wcid;u16 agg_ssn;bool send_bar;
drivers/net/wireless/mediatek/mt76/mt7603/main.c +1 -1
@@ -75,7 +75,7 @@ mt7603_add_interface(struct ieee80211_hwmt7603_wtbl_init (dev, idx, mvif->idx, bc_addr); mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx;rcu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid); out:
drivers/net/wireless/mediatek/mt76/mt7615/main.c +1 -1
@@ -234,7 +234,7 @@ static int mt7615_add_interface(struct ircu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid);if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; } ret =mt7615_mcu_add_dev_info (phy, vif, true);
drivers/net/wireless/mediatek/mt76/mt76x02_util.c +3 -1
@@ -292,7 +292,8 @@ mt76x02_vif_init(struct mt76x02_dev *devmt76_packet_id_init (&mvif->group_wcid); mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->group_wcid; +rcu_assign_pointer (dev->mt76.wcid[MT_VIF_WCID (idx)], &mvif->group_wcid); + mtxq->wcid =MT_VIF_WCID (idx); }int
@@ -345,6 +346,7 @@ void mt76x02_remove_interface(struct ieestruct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; dev->mt76.vif_mask &= ~BIT (mvif->idx); +rcu_assign_pointer (dev->mt76.wcid[mvif->group_wcid.idx],NULL );mt76_packet_id_flush (&dev->mt76, &mvif->group_wcid); }EXPORT_SYMBOL_GPL (mt76x02_remove_interface);
drivers/net/wireless/mediatek/mt76/mt7915/main.c +1 -1
@@ -246,7 +246,7 @@ static int mt7915_add_interface(struct ircu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid);if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; } if (vif->type != NL80211_IFTYPE_AP &&
drivers/net/wireless/mediatek/mt76/mt7921/main.c +1 -1
@@ -330,7 +330,7 @@ static int mt7921_add_interface(struct ircu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid);if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; } out:
drivers/net/wireless/mediatek/mt76/tx.c +4 -5
@@ -436,12 +436,11 @@ mt76_txq_stopped(struct mt76_queue *q)static int mt76_txq_send_burst (struct mt76_phy *phy,struct mt76_queue *q, -struct mt76_txq *mtxq) +struct mt76_txq *mtxq,struct mt76_wcid *wcid) {struct mt76_dev *dev = phy->dev;struct ieee80211_txq *txq =mtxq_to_txq (mtxq);enum mt76_txq_id qid =mt76_txq_get_qid (txq); -struct mt76_wcid *wcid = mtxq->wcid;struct ieee80211_tx_info *info;struct sk_buff *skb;int n_frames =1 ;
@@ -521,8 +520,8 @@ mt76_txq_schedule_list(struct mt76_phy *break ; mtxq = (struct mt76_txq *)txq->drv_priv; - wcid = mtxq->wcid; -if (wcid &&test_bit (MT_WCID_FLAG_PS , &wcid->flags)) + wcid =rcu_dereference (dev->wcid[mtxq->wcid]); +if (!wcid ||test_bit (MT_WCID_FLAG_PS , &wcid->flags))continue ;spin_lock_bh (&q->lock);
@@ -541,7 +540,7 @@ mt76_txq_schedule_list(struct mt76_phy * }if (!mt76_txq_stopped (q)) - n_frames =mt76_txq_send_burst (phy, q, mtxq); + n_frames =mt76_txq_send_burst (phy, q, mtxq, wcid);spin_unlock_bh (&q->lock);
Greg Kroah-Hartman
maintainerPATCH 814/879 cfg80211: declare MODULE_FIRMWARE for regulatory.db
In reply to Greg Kroah-HartmanFrom: Dimitri John Ledkov <[email protected]>
commit 7bc7981eeebe1b8e603ad2ffc5e84f4df76920dd upstream.
Add MODULE_FIRMWARE declarations for regulatory.db and regulatory.db.p7s such that userspace tooling can discover and include these files.
--- net/wireless/reg.c | 4 ++++ 1 file changed, 4 insertions(+)
net/wireless/reg.c +4 -0
@@ -807,6 +807,8 @@ static int __init load_builtin_regdb_keyreturn 0 ; } +MODULE_FIRMWARE ("regulatory.db.p7s" ); +static bool regdb_has_valid_signature (const u8 *data,unsigned int size) {const struct firmware *sig;
@@ -1078,6 +1080,8 @@ static void regdb_fw_cb(const struct firrelease_firmware (fw); } +MODULE_FIRMWARE ("regulatory.db" ); +static int query_regdb_file (const char *alpha2) {ASSERT_RTNL ();
Greg Kroah-Hartman
maintainerPATCH 815/879 mac80211: upgrade passive scan to active scan on DFS channels after beacon rx
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit b041b7b9de6e1d4362de855ab90f9d03ef323edd upstream.
In client mode, we can't connect to hidden SSID APs or SSIDs not advertised in beacons on DFS channels, since we're forced to passive scan. Fix this by sending out a probe request immediately after the first beacon, if active scan was requested by the user.
--- net/mac80211/ieee80211_i.h | 5 +++++ net/mac80211/scan.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+)
net/mac80211/ieee80211_i.h +5 -0
@@ -1148,6 +1148,9 @@ struct tpt_led_trigger {* a scan complete for an aborted scan. * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being * cancelled. +* @SCAN_BEACON_WAIT: Set whenever we're passive scanning because of radar/no-IR +* and could send a probe request after receiving a beacon. +* @SCAN_BEACON_DONE: Beacon received, we can now send a probe request */ enum {SCAN_SW_SCANNING ,
@@ -1156,6 +1159,8 @@ enum {SCAN_COMPLETED ,SCAN_ABORTED ,SCAN_HW_CANCELLED , +SCAN_BEACON_WAIT , + SCAN_BEACON_DONE, };/**
net/mac80211/scan.c +20 -0
@@ -281,6 +281,16 @@ void ieee80211_scan_rx(struct ieee80211_if (likely (!sdata1 && !sdata2))return ; +if (test_and_clear_bit (SCAN_BEACON_WAIT , &local->scanning)) { +/* +* we were passive scanning because of radar/no-IR, but +* the beacon/proberesp rx gives us an opportunity to upgrade +* to active scan +*/ +set_bit (SCAN_BEACON_DONE , &local->scanning); +ieee80211_queue_delayed_work (&local->hw, &local->scan_work,0 ); + } +if (ieee80211_is_probe_resp (mgmt->frame_control)) {struct cfg80211_scan_request *scan_req;struct cfg80211_sched_scan_request *sched_scan_req;
@@ -787,6 +797,8 @@ static int __ieee80211_start_scan(struct IEEE80211_CHAN_RADAR)) || !req->n_ssids) { next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; + if (req->n_ssids) + set_bit(SCAN_BEACON_WAIT, &local->scanning); } else {ieee80211_scan_state_send_probe (local, &next_delay); next_delay =IEEE80211_CHANNEL_TIME ;
@@ -998,6 +1010,8 @@ set_channel: !scan_req->n_ssids) { *next_delay =IEEE80211_PASSIVE_CHANNEL_TIME ; local->next_scan_state =SCAN_DECISION ; +if (scan_req->n_ssids) +set_bit (SCAN_BEACON_WAIT , &local->scanning);return ; }
@@ -1090,6 +1104,8 @@ void ieee80211_scan_work(struct work_str goto out; } +clear_bit (SCAN_BEACON_WAIT , &local->scanning); +/* * as long as no delay is required advance immediately * without scheduling a new work
@@ -1100,6 +1116,10 @@ void ieee80211_scan_work(struct work_str goto out_complete; } +if (test_and_clear_bit (SCAN_BEACON_DONE , &local->scanning) && + local->next_scan_state ==SCAN_DECISION ) + local->next_scan_state =SCAN_SEND_PROBE ; +switch (local->next_scan_state) {case SCAN_DECISION :/* if no more bands/channels left, complete scan */
Greg Kroah-Hartman
maintainerPATCH 816/879 um: virtio_uml: Fix broken device handling in time-travel
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit af9fb41ed315ce95f659f0b10b4d59a71975381d upstream.
If a device implementation crashes, virtio_uml will mark it as dead by calling virtio_break_device() and scheduling the work that will remove it.
This still seems like the right thing to do, but it's done directly while reading the message, and if time-travel is used, this is in the time-travel handler, outside of the normal Linux machinery. Therefore, we cannot acquire locks or do normal "linux-y" things because e.g. lockdep will be confused about the context.
Move handling this situation out of the read function and into the actual IRQ handler and response handling instead, so that in the case of time-travel we don't call it in the wrong context.
Chances are the system will still crash immediately, since the device implementation crashing may also cause the time- travel controller to go down, but at least all of that now happens without strange warnings from lockdep.
--- arch/um/drivers/virtio_uml.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
arch/um/drivers/virtio_uml.c +23 -10
@@ -63,6 +63,7 @@ struct virtio_uml_device { u8 config_changed_irq:1;uint64_t vq_irq_vq_map; +int recv_rc; };struct virtio_uml_vq_info {
@@ -148,14 +149,6 @@ static int vhost_user_recv(struct virtio rc =vhost_user_recv_header (fd, msg); -if (rc == -ECONNRESET && vu_dev->registered) { -struct virtio_uml_platform_data *pdata; - - pdata = vu_dev->pdata; - -virtio_break_device (&vu_dev->vdev); -schedule_work (&pdata->conn_broken_wk); - }if (rc)return rc; size = msg->header.size;
@@ -164,6 +157,21 @@ static int vhost_user_recv(struct virtioreturn full_read (fd, &msg->payload, size, false); } +static void vhost_user_check_reset (struct virtio_uml_device *vu_dev, +int rc) +{ +struct virtio_uml_platform_data *pdata = vu_dev->pdata; + +if (rc != -ECONNRESET ) +return ; + +if (!vu_dev->registered) +return ; + +virtio_break_device (&vu_dev->vdev); +schedule_work (&pdata->conn_broken_wk); +} +static int vhost_user_recv_resp (struct virtio_uml_device *vu_dev,struct vhost_user_msg *msg,size_t max_payload_size)
@@ -171,8 +179,10 @@ static int vhost_user_recv_resp(struct vint rc =vhost_user_recv (vu_dev, vu_dev->sock, msg, max_payload_size, true); -if (rc) +if (rc) { +vhost_user_check_reset (vu_dev, rc);return rc; + }if (msg->header.flags != (VHOST_USER_FLAG_REPLY |VHOST_USER_VERSION ))return -EPROTO ;
@@ -369,6 +379,7 @@ static irqreturn_t vu_req_read_message(ssizeof (msg.msg.payload) + sizeof(msg.extra_payload)); + vu_dev->recv_rc = rc;if (rc)return IRQ_NONE ;
@@ -412,7 +423,9 @@ static irqreturn_t vu_req_interrupt(intif (!um_irq_timetravel_handler_used ()) ret =vu_req_read_message (vu_dev,NULL ); -if (vu_dev->vq_irq_vq_map) { +if (vu_dev->recv_rc) { +vhost_user_check_reset (vu_dev, vu_dev->recv_rc); + }else if (vu_dev->vq_irq_vq_map) {struct virtqueue *vq;virtio_device_for_each_vq ((&vu_dev->vdev), vq) {
Greg Kroah-Hartman
maintainerPATCH 817/879 um: Use asm-generic/dma-mapping.h
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 365719035526e8eda214a1cedb2e1c96e969a0d7 upstream.
If DMA (PCI over virtio) is enabled, then some drivers may enable CONFIG_DMA_OPS as well, and then we pull in the x86 definition of get_arch_dma_ops(), which uses the dma_ops symbol, which isn't defined.
Since we don't have real DMA ops nor any kind of IOMMU fix this in the simplest possible way: pull in the asm-generic file instead of inheriting the x86 one. It's not clear why those drivers that do (e.g. VDPA) "select DMA_OPS", and if they'd even work with this, but chances are nobody will be wanting to do that anyway, so fixing the build failure is good enough.
--- arch/um/include/asm/Kbuild | 1 + 1 file changed, 1 insertion(+)
arch/um/include/asm/Kbuild +1 -0
@@ -4,6 +4,7 @@ generic-y += bug.h generic-y += compat.h generic-y += current.h generic-y += device.h +generic-y += dma-mapping.h generic-y += emergency-restart.h generic-y += exec.h generic-y += extable.h
Greg Kroah-Hartman
maintainerPATCH 818/879 um: chan_user: Fix winch_tramp() return value
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 57ae0b67b747031bc41fb44643aa5344ab58607e upstream.
The previous fix here was only partially correct, it did result in returning a proper error value in case of error, but it also clobbered the pid that we need to return from this function (not just zero for success).
As a result, it returned 0 here, but later this is treated as a pid and used to kill the process, but since it's now 0 we kill(0, SIGKILL), which makes UML kill itself rather than just the helper thread.
Fix that and make it more obvious by using a separate variable for the pid.
--- arch/um/drivers/chan_user.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
arch/um/drivers/chan_user.c +5 -4
@@ -220,7 +220,7 @@ static int winch_tramp(int fd, struct tt unsigned long *stack_out) {struct winch_data data; -int fds[2 ], n, err; +int fds[2 ], n, err, pid;char c; err =os_pipe (fds,1 ,1 );
@@ -238,8 +238,9 @@ static int winch_tramp(int fd, struct tt* problem with /dev/net/tun, which if held open by this * thread, prevents the TUN/TAP device from being reused. */ - err =run_helper_thread (winch_thread, &data,CLONE_FILES , stack_out); -if (err <0 ) { + pid =run_helper_thread (winch_thread, &data,CLONE_FILES , stack_out); +if (pid <0 ) { + err = pid;printk (UM_KERN_ERR "fork of winch_thread failed - errno = %d\n" , -err); goto out_close;
@@ -263,7 +264,7 @@ static int winch_tramp(int fd, struct tt goto out_close; } -return err; +return pid; out_close:close (fds[1 ]);
Greg Kroah-Hartman
maintainerPATCH 819/879 um: Fix out-of-bounds read in LDT setup
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
commit 2a4a62a14be1947fa945c5c11ebf67326381a568 upstream.
syscall_stub_data() expects the data_count parameter to be the number of longs, not bytes.
==================================================================
BUG: KASAN: stack-out-of-bounds in syscall_stub_data+0x70/0xe0 Read of size 128 at addr 000000006411f6f0 by task swapper/1 CPU: 0 PID: 1 Comm: swapper Not tainted 5.18.0+ #18 Call Trace: show_stack.cold+0x166/0x2a7 __dump_stack+0x3a/0x43 dump_stack_lvl+0x1f/0x27 print_report.cold+0xdb/0xf81 kasan_report+0x119/0x1f0 kasan_check_range+0x3a3/0x440 memcpy+0x52/0x140 syscall_stub_data+0x70/0xe0 write_ldt_entry+0xac/0x190 init_new_ldt+0x515/0x960 init_new_context+0x2c4/0x4d0 mm_init.constprop.0+0x5ed/0x760 mm_alloc+0x118/0x170 0x60033f48 do_one_initcall+0x1d7/0x860 0x60003e7b kernel_init+0x6e/0x3d4 new_thread_handler+0x1e7/0x2c0 The buggy address belongs to stack of task swapper/1 and is located at offset 64 in frame: init_new_ldt+0x0/0x960
This frame has 2 objects:
[32, 40) 'addr'
[64, 80) 'desc'
==================================================================
--- arch/x86/um/ldt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/x86/um/ldt.c +4 -2
@@ -23,9 +23,11 @@ static long write_ldt_entry(struct mm_id {long res;void *stub_addr; + +BUILD_BUG_ON (sizeof (*desc) %sizeof (long )); + res =syscall_stub_data (mm_idp, (unsigned long *)desc, - (sizeof (*desc) +sizeof (long ) -1 ) & - ~(sizeof (long ) -1 ), +sizeof (*desc) /sizeof (long ), addr, &stub_addr);if (!res) { unsigned long args[] = { func,
Greg Kroah-Hartman
maintainerPATCH 820/879 MIPS: IP27: Remove incorrect `cpu_has_fpu override
In reply to Greg Kroah-HartmanFrom: Maciej W. Rozycki <[email protected]>
commit 424c3781dd1cb401857585331eaaa425a13f2429 upstream.
Remove unsupported forcing of cpu_has_fpu' to 1, which makes the nofpu' kernel parameter non-functional, and also causes a link error:
ld: arch/mips/kernel/traps.o: in function `trap_init':
./arch/mips/include/asm/msa.h:(.init.text+0x348): undefined reference to `handle_fpe'
ld: ./arch/mips/include/asm/msa.h:(.init.text+0x354): undefined reference to `handle_fpe'
ld: ./arch/mips/include/asm/msa.h:(.init.text+0x360): undefined reference to `handle_fpe'
where the CONFIG_MIPS_FP_SUPPORT configuration option has been disabled.
--- arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h | 1 - 1 file changed, 1 deletion(-)
arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h +0 -1
@@ -25,7 +25,6 @@#define cpu_has_4kex 1#define cpu_has_3k_cache 0#define cpu_has_4k_cache 1 -#define cpu_has_fpu 1#define cpu_has_nofpuex 0#define cpu_has_32fpr 1#define cpu_has_counter 1
Greg Kroah-Hartman
maintainerPATCH 821/879 MIPS: IP30: Remove incorrect `cpu_has_fpu override
In reply to Greg Kroah-HartmanFrom: Maciej W. Rozycki <[email protected]>
commit f44b3e74c33fe04defeff24ebcae98c3bcc5b285 upstream.
Remove unsupported forcing of cpu_has_fpu' to 1, which makes the nofpu' kernel parameter non-functional, and also causes a link error:
ld: arch/mips/kernel/traps.o: in function `trap_init':
./arch/mips/include/asm/msa.h:(.init.text+0x348): undefined reference to `handle_fpe'
ld: ./arch/mips/include/asm/msa.h:(.init.text+0x354): undefined reference to `handle_fpe'
ld: ./arch/mips/include/asm/msa.h:(.init.text+0x360): undefined reference to `handle_fpe'
where the CONFIG_MIPS_FP_SUPPORT configuration option has been disabled.
--- arch/mips/include/asm/mach-ip30/cpu-feature-overrides.h | 1 - 1 file changed, 1 deletion(-)
arch/mips/include/asm/mach-ip30/cpu-feature-overrides.h +0 -1
@@ -28,7 +28,6 @@#define cpu_has_4kex 1#define cpu_has_3k_cache 0#define cpu_has_4k_cache 1 -#define cpu_has_fpu 1#define cpu_has_nofpuex 0#define cpu_has_32fpr 1#define cpu_has_counter 1
Greg Kroah-Hartman
maintainerPATCH 822/879 kexec_file: drop weak attribute from arch_kexec_apply_relocations[_add]
In reply to Greg Kroah-HartmanFrom: Naveen N. Rao <[email protected]>
commit 3e35142ef99fe6b4fe5d834ad43ee13cca10a2dc upstream.
Since commit d1bcae833b32f1 ("ELF: Don't generate unused section symbols") [1], binutils (v2.36+) started dropping section symbols that it thought were unused. This isn't an issue in general, but with kexec_file.c, gcc is placing kexec_arch_apply_relocations[_add] into a separate .text.unlikely section and the section symbol ".text.unlikely" is being dropped. Due to this, recordmcount is unable to find a non-weak symbol in .text.unlikely to generate a relocation record against.
Address this by dropping the weak attribute from these functions. Instead, follow the existing pattern of having architectures #define the name of the function they want to override in their headers.
[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d1bcae833b32f1
--- arch/s390/include/asm/kexec.h | 10 +++++++++ arch/x86/include/asm/kexec.h | 8 +++++++ include/linux/kexec.h | 46 ++++++++++++++++++++++++++++++++++-------- kernel/kexec_file.c | 34 ------------------------------- 4 files changed, 56 insertions(+), 42 deletions(-)
arch/s390/include/asm/kexec.h +10 -0
@@ -9,6 +9,8 @@#ifndef _S390_KEXEC_H#define _S390_KEXEC_H +#include <linux/module.h> +#include <asm/processor.h> #include <asm/page.h> #include <asm/setup.h>
@@ -83,4 +85,12 @@ struct kimage_arch {extern const struct kexec_file_ops s390_kexec_image_ops;extern const struct kexec_file_ops s390_kexec_elf_ops; +#ifdef CONFIG_KEXEC_FILE +struct purgatory_info ; +int arch_kexec_apply_relocations_add (struct purgatory_info *pi, +Elf_Shdr *section, +const Elf_Shdr *relsec, +const Elf_Shdr *symtab); +#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add +#endif #endif /*_S390_KEXEC_H */
arch/x86/include/asm/kexec.h +8 -0
@@ -186,6 +186,14 @@ extern int arch_kexec_post_alloc_pages(vextern void arch_kexec_pre_free_pages (void *vaddr,unsigned int pages);#define arch_kexec_pre_free_pages arch_kexec_pre_free_pages +#ifdef CONFIG_KEXEC_FILE +struct purgatory_info ; +int arch_kexec_apply_relocations_add (struct purgatory_info *pi, +Elf_Shdr *section, +const Elf_Shdr *relsec, +const Elf_Shdr *symtab); +#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add +#endif #endif typedef void crash_vmclear_fn (void );
include/linux/kexec.h +38 -8
58 lines not on this page · raw message
kernel/kexec_file.c +0 -34
@@ -109,40 +109,6 @@ int __weak arch_kexec_kernel_verify_sig(#endif /* -* arch_kexec_apply_relocations_add - apply relocations of type RELA -* @pi: Purgatory to be relocated. -* @section: Section relocations applying to. -* @relsec: Section containing RELAs. -* @symtab: Corresponding symtab. -* -* Return: 0 on success, negative errno on error. -*/ -int __weak -arch_kexec_apply_relocations_add (struct purgatory_info *pi,Elf_Shdr *section, -const Elf_Shdr *relsec,const Elf_Shdr *symtab) -{ -pr_err ("RELA relocation unsupported.\n" ); -return -ENOEXEC ; -} - -/* -* arch_kexec_apply_relocations - apply relocations of type REL -* @pi: Purgatory to be relocated. -* @section: Section relocations applying to. -* @relsec: Section containing RELs. -* @symtab: Corresponding symtab. -* -* Return: 0 on success, negative errno on error. -*/ -int __weak -arch_kexec_apply_relocations (struct purgatory_info *pi,Elf_Shdr *section, -const Elf_Shdr *relsec,const Elf_Shdr *symtab) -{ -pr_err ("REL relocation unsupported.\n" ); -return -ENOEXEC ; -} - -/* * Free up memory used by kernel, initrd, and command line. This is temporary * memory allocation which is not needed any more after these buffers have * been loaded into separate segments and have been copied elsewhere.
Greg Kroah-Hartman
maintainerPATCH 823/879 ftrace: Clean up hash direct_functions on register failures
In reply to Greg Kroah-HartmanFrom: Song Liu <[email protected]>
commit 7d54c15cb89a29a5f59e5ffc9ee62e6591769ef1 upstream.
We see the following GPF when register_ftrace_direct fails:
[ ] general protection fault, probably for non-canonical address \
0x200000000000010: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI
[...]
[ ] RIP: 0010:ftrace_find_rec_direct+0x53/0x70
[ ] Code: 48 c1 e0 03 48 03 42 08 48 8b 10 31 c0 48 85 d2 74 [...] [ ] RSP: 0018:ffffc9000138bc10 EFLAGS: 00010206
[ ] RAX: 0000000000000000 RBX: ffffffff813e0df0 RCX: 000000000000003b [ ] RDX: 0200000000000000 RSI: 000000000000000c RDI: ffffffff813e0df0 [ ] RBP: ffffffffa00a3000 R08: ffffffff81180ce0 R09: 0000000000000001 [ ] R10: ffffc9000138bc18 R11: 0000000000000001 R12: ffffffff813e0df0 [ ] R13: ffffffff813e0df0 R14: ffff888171b56400 R15: 0000000000000000 [ ] FS: 00007fa9420c7780(0000) GS:ffff888ff6a00000(0000) knlGS:000000000 [ ] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ ] CR2: 000000000770d000 CR3: 0000000107d50003 CR4: 0000000000370ee0 [ ] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ ] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ ] Call Trace:
[ ] <TASK> [ ] register_ftrace_direct+0x54/0x290 [ ] ? render_sigset_t+0xa0/0xa0 [ ] bpf_trampoline_update+0x3f5/0x4a0 [ ] ? 0xffffffffa00a3000 [ ] bpf_trampoline_link_prog+0xa9/0x140 [ ] bpf_tracing_prog_attach+0x1dc/0x450 [ ] bpf_raw_tracepoint_open+0x9a/0x1e0 [ ] ? find_held_lock+0x2d/0x90 [ ] ? lock_release+0x150/0x430 [ ] __sys_bpf+0xbd6/0x2700 [ ] ? lock_is_held_type+0xd8/0x130 [ ] __x64_sys_bpf+0x1c/0x20 [ ] do_syscall_64+0x3a/0x80 [ ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ ] RIP: 0033:0x7fa9421defa9
[ ] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 9 f8 [...] [ ] RSP: 002b:00007ffed743bd78 EFLAGS: 00000246 ORIG_RAX: 0000000000000141 [ ] RAX: ffffffffffffffda RBX: 00000000069d2480 RCX: 00007fa9421defa9 [ ] RDX: 0000000000000078 RSI: 00007ffed743bd80 RDI: 0000000000000011 [ ] RBP: 00007ffed743be00 R08: 0000000000bb7270 R09: 0000000000000000 [ ] R10: 00000000069da210 R11: 0000000000000246 R12: 0000000000000001 [ ] R13: 00007ffed743c4b0 R14: 00000000069d2480 R15: 0000000000000001 [ ] </TASK>
[ ] Modules linked in: klp_vm(OK)
[ ] ---[ end trace 0000000000000000 ]---
One way to trigger this is:
1. load a livepatch that patches kernel function xxx;
2. run bpftrace -e 'kfunc:xxx {}', this will fail (expected for now);
3. repeat #2 => gpf.
This is because the entry is added to direct_functions, but not removed. Fix this by remove the entry from direct_functions when register_ftrace_direct fails.
Also remove the last trailing space from ftrace.c, so we don't have to worry about it anymore.
--- kernel/trace/ftrace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/trace/ftrace.c +2 -3
@@ -4465,7 +4465,7 @@ int ftrace_func_mapper_add_ip(struct ftr* @ip: The instruction pointer address to remove the data from * * Returns the data if it is found, otherwise NULL. -* Note, if the data pointer is used as the data itself, (see +* Note, if the data pointer is used as the data itself, (see * ftrace_func_mapper_find_ip(), then the return value may be meaningless, * if the data pointer was set to zero. */
@@ -5195,8 +5195,6 @@ int register_ftrace_direct(unsigned long goto out_unlock; ret =ftrace_set_filter_ip (&direct_ops, ip,0 ,0 ); -if (ret) -remove_hash_entry (direct_functions, entry);if (!ret && !(direct_ops.flags &FTRACE_OPS_FL_ENABLED )) { ret =register_ftrace_function (&direct_ops);
@@ -5205,6 +5203,7 @@ int register_ftrace_direct(unsigned long }if (ret) { +remove_hash_entry (direct_functions, entry);kfree (entry);if (!direct->count) {list_del_rcu (&direct->next);
Greg Kroah-Hartman
maintainerPATCH 824/879 ksmbd: fix outstanding credits related bugs
In reply to Greg Kroah-HartmanFrom: Hyunchul Lee <[email protected]>
commit 376b9133826865568167b4091ef92a68c4622b87 upstream.
outstanding credits must be initialized to 0,
because it means the sum of credits consumed by
in-flight requests.
And outstanding credits must be compared with
total credits in smb2_validate_credit_charge(),
because total credits are the sum of credits
granted by ksmbd.
This patch fix the following error,
while frametest with Windows clients:
Limits exceeding the maximum allowable outstanding requests, given : 128, pending : 8065
--- fs/ksmbd/connection.c | 2 +- fs/ksmbd/smb2misc.c | 2 +- fs/ksmbd/smb_common.c | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-)
fs/ksmbd/connection.c +1 -1
@@ -62,7 +62,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(voidatomic_set (&conn->req_running,0 );atomic_set (&conn->r_count,0 ); conn->total_credits =1 ; - conn->outstanding_credits =1 ; + conn->outstanding_credits =0 ;init_waitqueue_head (&conn->req_running_q);INIT_LIST_HEAD (&conn->conns_list);
fs/ksmbd/smb2misc.c +1 -1
@@ -338,7 +338,7 @@ static int smb2_validate_credit_charge(s ret =1 ; } -if ((u64 )conn->outstanding_credits + credit_charge > conn->vals->max_credits) { +if ((u64 )conn->outstanding_credits + credit_charge > conn->total_credits) {ksmbd_debug (SMB ,"Limits exceeding the maximum allowable outstanding requests, given : %u, pending : %u\n" , credit_charge, conn->outstanding_credits); ret =1 ;
fs/ksmbd/smb_common.c +3 -1
@@ -140,8 +140,10 @@ int ksmbd_verify_smb_message(struct ksmb hdr = work->request_buf;if (*(__le32 *)hdr->Protocol ==SMB1_PROTO_NUMBER && - hdr->Command ==SMB_COM_NEGOTIATE ) + hdr->Command ==SMB_COM_NEGOTIATE ) { + work->conn->outstanding_credits++;return 0 ; + }return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 825/879 iommu/msm: Fix an incorrect NULL check on list iterator
In reply to Greg Kroah-HartmanFrom: Xiaomeng Tong <[email protected]>
commit 8b9ad480bd1dd25f4ff4854af5685fa334a2f57a upstream.
The bug is here:
if (!iommu || iommu->dev->of_node != spec->np) {The list iterator value 'iommu' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found (in fact, it will point to a invalid structure object containing HEAD).
To fix the bug, use a new value 'iter' as the list iterator, while use the old value 'iommu' as a dedicated variable to point to the found one, and remove the unneeded check for 'iommu->dev->of_node != spec->np' outside the loop.
--- drivers/iommu/msm_iommu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/iommu/msm_iommu.c +7 -4
@@ -610,16 +610,19 @@ static void insert_iommu_master(struct dstatic int qcom_iommu_of_xlate (struct device *dev,struct of_phandle_args *spec) { -struct msm_iommu_dev *iommu; +struct msm_iommu_dev *iommu =NULL , *iter;unsigned long flags;int ret =0 ;spin_lock_irqsave (&msm_iommu_lock, flags); -list_for_each_entry (iommu, &qcom_iommu_devices, dev_node) -if (iommu->dev->of_node == spec->np) +list_for_each_entry (iter, &qcom_iommu_devices, dev_node) { +if (iter->dev->of_node == spec->np) { + iommu = iter;break ; + } + } -if (!iommu || iommu->dev->of_node != spec->np) { +if (!iommu) { ret = -ENODEV ; goto fail; }
Greg Kroah-Hartman
maintainerPATCH 826/879 iommu/dma: Fix iova map result check bug
In reply to Greg Kroah-HartmanFrom: Yunfei Wang <[email protected]>
commit a3884774d731f03d3a3dd4fb70ec2d9341ceb39d upstream.
The data type of the return value of the iommu_map_sg_atomic is ssize_t, but the data type of iova size is size_t, e.g. one is int while the other is unsigned int.
When iommu_map_sg_atomic return value is compared with iova size, it will force the signed int to be converted to unsigned int, if iova map fails and iommu_map_sg_atomic return error code is less than 0, then (ret < iova_len) is false, which will to cause not do free iova, and the master can still successfully get the iova of map fail, which is not expected.
Therefore, we need to check the return value of iommu_map_sg_atomic in two cases according to whether it is less than 0.
--- drivers/iommu/dma-iommu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/iommu/dma-iommu.c +4 -3
@@ -776,6 +776,7 @@ static struct page **__iommu_dma_alloc_nunsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap;struct page **pages;dma_addr_t iova; +ssize_t ret;if (static_branch_unlikely (&iommu_deferred_attach_enabled) &&iommu_deferred_attach (dev, domain))
@@ -813,8 +814,8 @@ static struct page **__iommu_dma_alloc_narch_dma_prep_coherent (sg_page (sg), sg->length); } -if (iommu_map_sg_atomic (domain, iova, sgt->sgl, sgt->orig_nents, ioprot) - < size) + ret =iommu_map_sg_atomic (domain, iova, sgt->sgl, sgt->orig_nents, ioprot); +if (ret <0 || ret < size) goto out_free_sg; sgt->sgl->dma_address = iova;
@@ -1209,7 +1210,7 @@ static int iommu_dma_map_sg(struct devic* implementation - it knows better than we do. */ ret =iommu_map_sg_atomic (domain, iova, sg, nents, prot); -if (ret < iova_len) +if (ret <0 || ret < iova_len) goto out_free_iova;return __finalise_sg (dev, sg, nents, iova);
Greg Kroah-Hartman
maintainerPATCH 827/879 kprobes: Fix build errors with CONFIG_KRETPROBES=n
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
commit 43994049180704fd1faf78623fabd9a5cd443708 upstream.
Max Filippov reported:
When building kernel with CONFIG_KRETPROBES=n kernel/kprobes.c compilation fails with the following messages:
kernel/kprobes.c: In function ‘recycle_rp_inst’:
kernel/kprobes.c:1273:32: error: implicit declaration of function
‘get_kretprobe’
kernel/kprobes.c: In function ‘kprobe_flush_task’:
kernel/kprobes.c:1299:35: error: ‘struct task_struct’ has no member
named ‘kretprobe_instances’
This came from the commit d741bf41d7c7 ("kprobes: Remove kretprobe hash") which introduced get_kretprobe() and kretprobe_instances member in task_struct when CONFIG_KRETPROBES=y, but did not make recycle_rp_inst() and kprobe_flush_task() depending on CONFIG_KRETPORBES.
Since those functions are only used for kretprobe, move those functions into #ifdef CONFIG_KRETPROBE area.
--- include/linux/kprobes.h | 2 kernel/kprobes.c | 144 +++++++++++++++++++++++------------------------- 2 files changed, 72 insertions(+), 74 deletions(-)
include/linux/kprobes.h +1 -1
@@ -424,7 +424,7 @@ void unregister_kretprobe(struct kretproint register_kretprobes (struct kretprobe **rps,int num);void unregister_kretprobes (struct kretprobe **rps,int num); -#ifdef CONFIG_KRETPROBE_ON_RETHOOK +#if defined(CONFIG_KRETPROBE_ON_RETHOOK ) || !defined(CONFIG_KRETPROBES )#define kprobe_flush_task (tk) do {} while (0)#else void kprobe_flush_task (struct task_struct *tk);
kernel/kprobes.c +71 -73
156 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 828/879 Revert "mm/cma.c: remove redundant cma_mutex lock"
In reply to Greg Kroah-HartmanFrom: Dong Aisheng <[email protected]>
commit 60a60e32cf91169840abcb4a80f0b0df31708ba7 upstream.
This reverts commit a4efc174b382fcdb which introduced a regression issue that when there're multiple processes allocating dma memory in parallel by calling dma_alloc_coherent(), it may fail sometimes as follows:
Error log:
cma: cma_alloc: linux,cma: alloc failed, req-size: 148 pages, ret: -16
cma: number of available pages:
3@125+20@172+12@236+4@380+32@736+17@2287+23@2473+20@36076+99@40477+108@40852+44@41108+20@41196+108@41364+108@41620+ 108@42900+108@43156+483@44061+1763@45341+1440@47712+20@49324+20@49388+5076@49452+2304@55040+35@58141+20@58220+20@58284+ 7188@58348+84@66220+7276@66452+227@74525+6371@75549=> 33161 free of 81920 total pages
When issue happened, we saw there were still 33161 pages (129M) free CMA memory and a lot available free slots for 148 pages in CMA bitmap that we want to allocate.
When dumping memory info, we found that there was also ~342M normal memory, but only 1352K CMA memory left in buddy system while a lot of pageblocks were isolated.
Memory info log:
Normal free:351096kB min:30000kB low:37500kB high:45000kB reserved_highatomic:0KB
active_anon:98060kB inactive_anon:98948kB active_file:60864kB inactive_file:31776kB unevictable:0kB writepending:0kB present:1048576kB managed:1018328kB mlocked:0kB bounce:0kB free_pcp:220kB local_pcp:192kB free_cma:1352kB lowmem_reserve[]: 0 0 0 Normal: 78*4kB (UECI) 1772*8kB (UMECI) 1335*16kB (UMECI) 360*32kB (UMECI) 65*64kB (UMCI) 36*128kB (UMECI) 16*256kB (UMCI) 6*512kB (EI) 8*1024kB (UEI) 4*2048kB (MI) 8*4096kB (EI) 8*8192kB (UI) 3*16384kB (EI) 8*32768kB (M) = 489288kB
The root cause of this issue is that since commit a4efc174b382 ("mm/cma.c:
remove redundant cma_mutex lock"), CMA supports concurrent memory allocation. It's possible that the memory range process A trying to alloc has already been isolated by the allocation of process B during memory migration.
The problem here is that the memory range isolated during one allocation by start_isolate_page_range() could be much bigger than the real size we want to alloc due to the range is aligned to MAX_ORDER_NR_PAGES.
Taking an ARMv7 platform with 1G memory as an example, when MAX_ORDER_NR_PAGES is big (e.g. 32M with max_order 14) and CMA memory is relatively small (e.g. 128M), there're only 4 MAX_ORDER slot, then it's very easy that all CMA memory may have already been isolated by other processes when one trying to allocate memory using dma_alloc_coherent(). Since current CMA code will only scan one time of whole available CMA memory, then dma_alloc_coherent() may easy fail due to contention with other processes.
This patch simply falls back to the original method that using cma_mutex to make alloc_contig_range() run sequentially to avoid the issue.
--- mm/cma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
mm/cma.c +3 -1
@@ -37,6 +37,7 @@struct cma cma_areas[MAX_CMA_AREAS ];unsigned cma_area_count; +static DEFINE_MUTEX (cma_mutex);phys_addr_t cma_get_base (const struct cma *cma) {
@@ -468,9 +469,10 @@ struct page *cma_alloc(struct cma *cma,spin_unlock_irq (&cma->lock); pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); +mutex_lock (&cma_mutex); ret =alloc_contig_range (pfn, pfn + count,MIGRATE_CMA ,GFP_KERNEL | (no_warn ? __GFP_NOWARN :0 )); - +mutex_unlock (&cma_mutex);if (ret ==0 ) { page =pfn_to_page (pfn);break ;
Greg Kroah-Hartman
maintainerPATCH 829/879 mm/page_owner: use strscpy() instead of strlcpy()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit cd8c1fd8cdd14158f2d8bea2d1bfe8015dccfa3a upstream.
current->comm[] is not a string (no guarantee for a zero byte in it).
strlcpy(s1, s2, l) is calling strlen(s2), potentially causing out-of-bound access, as reported by syzbot:
detected buffer overflow in __fortify_strlen
------------[ cut here ]------------ kernel BUG at lib/string_helpers.c:980! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 4087 Comm: dhcpcd-run-hooks Not tainted 5.18.0-rc3-syzkaller-01537-g20b87e7c29df #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:fortify_panic+0x18/0x1a lib/string_helpers.c:980 Code: 8c e8 c5 ba e1 fa e9 23 0f bf fa e8 0b 5d 8c f8 eb db 55 48 89 fd e8 e0 49 40 f8 48 89 ee 48 c7 c7 80 f5 26 8a e8 99 09 f1 ff <0f> 0b e8 ca 49 40 f8 48 8b 54 24 18 4c 89 f1 48 c7 c7 00 00 27 8a RSP: 0018:ffffc900000074a8 EFLAGS: 00010286
RAX: 000000000000002c RBX: ffff88801226b728 RCX: 0000000000000000 RDX: ffff8880198e0000 RSI: ffffffff81600458 RDI: fffff52000000e87 RBP: ffffffff89da2aa0 R08: 000000000000002c R09: 0000000000000000 R10: ffffffff815fae2e R11: 0000000000000000 R12: ffff88801226b700 R13: ffff8880198e0830 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff8880b9c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f5876ad6ff8 CR3: 000000001a48c000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600 Call Trace: <IRQ> __fortify_strlen include/linux/fortify-string.h:128 [inline] strlcpy include/linux/fortify-string.h:143 [inline] __set_page_owner_handle+0x2b1/0x3e0 mm/page_owner.c:171 __set_page_owner+0x3e/0x50 mm/page_owner.c:190 prep_new_page mm/page_alloc.c:2441 [inline] get_page_from_freelist+0xba2/0x3e00 mm/page_alloc.c:4182 __alloc_pages+0x1b2/0x500 mm/page_alloc.c:5408 alloc_pages+0x1aa/0x310 mm/mempolicy.c:2272 alloc_slab_page mm/slub.c:1799 [inline] allocate_slab+0x26c/0x3c0 mm/slub.c:1944 new_slab mm/slub.c:2004 [inline] ___slab_alloc+0x8df/0xf20 mm/slub.c:3005 __slab_alloc.constprop.0+0x4d/0xa0 mm/slub.c:3092 slab_alloc_node mm/slub.c:3183 [inline] slab_alloc mm/slub.c:3225 [inline] __kmem_cache_alloc_lru mm/slub.c:3232 [inline] kmem_cache_alloc+0x360/0x3b0 mm/slub.c:3242 dst_alloc+0x146/0x1f0 net/core/dst.c:92
--- mm/page_owner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/page_owner.c +1 -1
@@ -168,7 +168,7 @@ static inline void __set_page_owner_hand page_owner->pid = current->pid; page_owner->tgid = current->tgid; page_owner->ts_nsec =local_clock (); -strlcpy (page_owner->comm, current->comm, +strscpy (page_owner->comm, current->comm,sizeof (page_owner->comm));__set_bit (PAGE_EXT_OWNER , &page_ext->flags);__set_bit (PAGE_EXT_OWNER_ALLOCATED , &page_ext->flags);
Greg Kroah-Hartman
maintainerPATCH 830/879 mm/page_alloc: always attempt to allocate at least one page during bulk allocation
In reply to Greg Kroah-HartmanFrom: Mel Gorman <[email protected]>
commit c572e4888ad1be123c1516ec577ad30a700bbec4 upstream.
Peter Pavlisko reported the following problem on kernel bugzilla 216007.
When I try to extract an uncompressed tar archive (2.6 milion files, 760.3 GiB in size) on newly created (empty) XFS file system, after first low tens of gigabytes extracted the process hangs in iowait indefinitely. One CPU core is 100% occupied with iowait, the other CPU core is idle (on 2-core Intel Celeron G1610T).
It was bisected to c9fa563072e1 ("xfs: use alloc_pages_bulk_array() for buffers") but XFS is only the messenger. The problem is that nothing is waking kswapd to reclaim some pages at a time the PCP lists cannot be refilled until some reclaim happens. The bulk allocator checks that there are some pages in the array and the original intent was that a bulk allocator did not necessarily need all the requested pages and it was best to return as quickly as possible.
This was fine for the first user of the API but both NFS and XFS require the requested number of pages be available before making progress. Both could be adjusted to call the page allocator directly if a bulk allocation fails but it puts a burden on users of the API. Adjust the semantics to attempt at least one allocation via __alloc_pages() before returning so kswapd is woken if necessary.
It was reported via bugzilla that the patch addressed the problem and that the tar extraction completed successfully. This may also address bug 215975 but has yet to be confirmed.
--- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page_alloc.c +2 -2
@@ -5324,8 +5324,8 @@ unsigned long __alloc_pages_bulk(gfp_t g page =__rmqueue_pcplist (zone,0 , ac.migratetype, alloc_flags, pcp, pcp_list);if (unlikely (!page)) { -/* Try and get at least one page */ -if (!nr_populated) +/* Try and allocate at least one page */ +if (!nr_account) goto failed_irq;break ; }
Greg Kroah-Hartman
maintainerPATCH 831/879 nodemask.h: fix compilation error with GCC12
In reply to Greg Kroah-HartmanFrom: Christophe de Dinechin <[email protected]>
commit 37462a920392cb86541650a6f4121155f11f1199 upstream.
With gcc version 12.0.1 20220401 (Red Hat 12.0.1-0), building with defconfig results in the following compilation error:
| CC mm/swapfile.o | mm/swapfile.c: In function `setup_swap_info': | mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds | of `struct plist_node[]' [-Werror=array-bounds] | 2291 | p->avail_lists[i].prio = 1; | | ~~~~~~~~~~~~~~^~~ | In file included from mm/swapfile.c:16: | ./include/linux/swap.h:292:27: note: while referencing `avail_lists' | 292 | struct plist_node avail_lists[]; /* | | ^~~~~~~~~~~
This is due to the compiler detecting that the mask in node_states[__state] could theoretically be zero, which would lead to first_node() returning -1 through find_first_bit.
I believe that the warning/error is legitimate. I first tried adding a test to check that the node mask is not emtpy, since a similar test exists in the case where MAX_NUMNODES == 1.
However, adding the if statement causes other warnings to appear in for_each_cpu_node_but, because it introduces a dangling else ambiguity. And unfortunately, GCC is not smart enough to detect that the added test makes the case where (node) == -1 impossible, so it still complains with the same message.
This is why I settled on replacing that with a harmless, but relatively useless (node) >= 0 test. Based on the warning for the dangling else, I also decided to fix the case where MAX_NUMNODES == 1 by moving the condition inside the for loop. It will still only be tested once. This ensures that the meaning of an else following for_each_node_mask or derivatives would not silently have a different meaning depending on the configuration.
--- include/linux/nodemask.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
include/linux/nodemask.h +6 -7
@@ -375,14 +375,13 @@ static inline void __nodes_fold(nodemask }#if MAX_NUMNODES >1 -#define for_each_node_mask (node, mask) \ - for ((node) = first_node(mask); \ - (node) < MAX_NUMNODES; \ - (node) = next_node((node), (mask))) +#define for_each_node_mask (node, mask) \ + for ((node) = first_node(mask); \ + (node >= 0) && (node) < MAX_NUMNODES; \ + (node) = next_node((node), (mask)))#else /* MAX_NUMNODES == 1 */ -#define for_each_node_mask (node, mask) \ - if (!nodes_empty(mask)) \ - for ((node) = 0; (node) < 1; (node)++) +#define for_each_node_mask (node, mask) \ + for ((node) = 0; (node) < 1 && !nodes_empty(mask); (node)++)#endif /* MAX_NUMNODES */ /*
Greg Kroah-Hartman
maintainerPATCH 832/879 hugetlb: fix huge_pmd_unshare address update
In reply to Greg Kroah-HartmanFrom: Mike Kravetz <[email protected]>
commit 48381273f8734d28ef56a5bdf1966dd8530111bc upstream.
The routine huge_pmd_unshare() is passed a pointer to an address associated with an area which may be unshared. If unshare is successful this address is updated to 'optimize' callers iterating over huge page addresses. For the optimization to work correctly, address should be updated to the last huge page in the unmapped/unshared area. However, in the common case where the passed address is PUD_SIZE aligned, the address is incorrectly updated to the address of the preceding huge page. That wastes CPU cycles as the unmapped/unshared range is scanned twice.
--- mm/hugetlb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
mm/hugetlb.c +8 -1
@@ -6562,7 +6562,14 @@ int huge_pmd_unshare(struct mm_struct *mpud_clear (pud);put_page (virt_to_page (ptep));mm_dec_nr_pmds (mm); - *addr =ALIGN (*addr,HPAGE_SIZE *PTRS_PER_PTE ) -HPAGE_SIZE ; +/* +* This update of passed address optimizes loops sequentially +* processing addresses in increments of huge page size (PMD_SIZE +* in this case). By clearing the pud, a PUD_SIZE area is unmapped. +* Update address to the 'last page' in the cleared area so that +* calling loop can move to first page past this area. +*/ + *addr |=PUD_SIZE -PMD_SIZE ;return 1 ; }
Greg Kroah-Hartman
maintainerPATCH 833/879 mm/memremap: fix missing call to untrack_pfn() in pagemap_range()
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
commit a04e1928e2ead144dc2f369768bc0a0f3110af89 upstream.
We forget to call untrack_pfn() to pair with track_pfn_remap() when range is not allowed to hotplug. Fix it by jump err_kasan.
--- mm/memremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memremap.c +1 -1
@@ -214,7 +214,7 @@ static int pagemap_range(struct dev_pageif (!mhp_range_allowed (range->start,range_len (range), !is_private)) { error = -EINVAL ; - goto err_pfn_remap; + goto err_kasan; }mem_hotplug_begin ();
Greg Kroah-Hartman
maintainerPATCH 834/879 xtensa/simdisk: fix proc_read_simdisk()
In reply to Greg Kroah-HartmanFrom: Yi Yang <[email protected]>
commit b011946d039d66bbc7102137e98cc67e1356aa87 upstream.
The commit a69755b18774 ("xtensa simdisk: switch to proc_create_data()") split read operation into two parts, first retrieving the path when it's non-null and second retrieving the trailing '\n'. However when the path is non-null the first simple_read_from_buffer updates ppos, and the second simple_read_from_buffer returns 0 if ppos is greater than 1 (i.e. almost always). As a result reading from that proc file is almost always empty.
Fix it by making a temporary copy of the path with the trailing '\n' and using simple_read_from_buffer on that copy.
--- arch/xtensa/platforms/iss/simdisk.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
arch/xtensa/platforms/iss/simdisk.c +12 -6
@@ -211,12 +211,18 @@ static ssize_t proc_read_simdisk(structstruct simdisk *dev =pde_data (file_inode (file));const char *s = dev->filename;if (s) { -ssize_t n =simple_read_from_buffer (buf, size, ppos, - s,strlen (s)); -if (n <0 ) -return n; - buf += n; - size -= n; +ssize_t len =strlen (s); +char *temp =kmalloc (len +2 ,GFP_KERNEL ); + +if (!temp) +return -ENOMEM ; + + len =scnprintf (temp, len +2 ,"%s\n" , s); + len =simple_read_from_buffer (buf, size, ppos, + temp, len); + +kfree (temp); +return len; }return simple_read_from_buffer (buf, size, ppos,"\n" ,1 ); }
Greg Kroah-Hartman
maintainerPATCH 835/879 rtl818x: Prevent using not initialized queues
In reply to Greg Kroah-HartmanFrom: Alexander Wetzel <[email protected]>
commit 746285cf81dc19502ab238249d75f5990bd2d231 upstream.
Using not existing queues can panic the kernel with rtl8180/rtl8185 cards. Ignore the skb priority for those cards, they only have one tx queue. Pierre Asselin ([email protected]) reported the kernel crash in the Gentoo forum:
https://forums.gentoo.org/viewtopic-t-1147832-postdays-0-postorder-asc-start-25.html
He also confirmed that this patch fixes the issue. In summary this happened:
After updating wpa_supplicant from 2.9 to 2.10 the kernel crashed with a "divide error: 0000" when connecting to an AP. Control port tx now tries to use IEEE80211_AC_VO for the priority, which wpa_supplicants starts to use in 2.10.
Since only the rtl8187se part of the driver supports QoS, the priority of the skb is set to IEEE80211_AC_BE (2) by mac80211 for rtl8180/rtl8185 cards.
rtl8180 is then unconditionally reading out the priority and finally crashes on drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c line 544 without this patch:
idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries
"ring->entries" is zero for rtl8180/rtl8185 cards, tx_ring[2] never got initialized.
--- drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +6 -2
@@ -460,8 +460,10 @@ static void rtl8180_tx(struct ieee80211_struct rtl8180_priv *priv = dev->priv;struct rtl8180_tx_ring *ring;struct rtl8180_tx_desc *entry; +unsigned int prio =0 ;unsigned long flags; -unsigned int idx, prio, hw_prio; +unsigned int idx, hw_prio; +dma_addr_t mapping;u32 tx_flags;u8 rc_flags;
@@ -470,7 +472,9 @@ static void rtl8180_tx(struct ieee80211_/* do arithmetic and then convert to le16 */ u16 frame_duration =0 ; - prio =skb_get_queue_mapping (skb); +/* rtl8180/rtl8185 only has one useable tx queue */ +if (dev->queues >IEEE80211_AC_BK ) + prio =skb_get_queue_mapping (skb); ring = &priv->tx_ring[prio]; mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
Greg Kroah-Hartman
maintainerPATCH 836/879 ASoC: rt5514: Fix event generation for "DSP Voice Wake Up" control
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit 4213ff556740bb45e2d9ff0f50d056c4e7dd0921 upstream.
The driver has a custom put function for "DSP Voice Wake Up" which does not generate event notifications on change, instead returning 0. Since we already exit early in the case that there is no change this can be fixed by unconditionally returning 1 at the end of the function.
--- sound/soc/codecs/rt5514.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/rt5514.c +1 -1
@@ -419,7 +419,7 @@ static int rt5514_dsp_voice_wake_up_put( } } -return 0 ; +return 1 ; }static const struct snd_kcontrol_new rt5514_snd_controls[] = {
Greg Kroah-Hartman
maintainerPATCH 837/879 carl9170: tx: fix an incorrect use of list iterator
In reply to Greg Kroah-HartmanFrom: Xiaomeng Tong <[email protected]>
commit 54a6f29522da3c914da30e50721dedf51046449a upstream.
If the previous list_for_each_entry_continue_rcu() don't exit early (no goto hit inside the loop), the iterator 'cvif' after the loop will be a bogus pointer to an invalid structure object containing the HEAD (&ar->vif_list). As a result, the use of 'cvif' after that will lead to a invalid memory access (i.e., 'cvif->id': the invalid pointer dereference when return back to/after the callsite in the carl9170_update_beacon()).
The original intention should have been to return the valid 'cvif' when found in list, NULL otherwise. So just return NULL when no entry found, to fix this bug.
--- drivers/net/wireless/ath/carl9170/tx.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/ath/carl9170/tx.c +3 -0
@@ -1558,6 +1558,9 @@ static struct carl9170_vif_info *carl917 goto out; } }while (ar->beacon_enabled && i--); + +/* no entry found in list */ +return NULL ; } out:
Greg Kroah-Hartman
maintainerPATCH 838/879 stm: ltdc: fix two incorrect NULL checks on list iterator
In reply to Greg Kroah-HartmanFrom: Xiaomeng Tong <[email protected]>
commit 2e6c86be0e57079d1fb6c7c7e5423db096d0548a upstream.
The two bugs are here:
if (encoder) {
if (bridge && bridge->timings)The list iterator value 'encoder/bridge' will *always* be set and non-NULL by drm_for_each_encoder()/list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found.
To fix the bug, use a new variable '*_iter' as the list iterator, while use the old variable 'encoder/bridge' as a dedicated pointer to point to the found element.
--- drivers/gpu/drm/stm/ltdc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/gpu/drm/stm/ltdc.c +10 -6
@@ -869,8 +869,8 @@ static void ltdc_crtc_mode_set_nofb(strustruct drm_device *ddev = crtc->dev;struct drm_connector_list_iter iter;struct drm_connector *connector =NULL ; -struct drm_encoder *encoder =NULL ; -struct drm_bridge *bridge =NULL ; +struct drm_encoder *encoder =NULL , *en_iter; +struct drm_bridge *bridge =NULL , *br_iter;struct drm_display_mode *mode = &crtc->state->adjusted_mode;u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;u32 total_width, total_height;
@@ -880,15 +880,19 @@ static void ltdc_crtc_mode_set_nofb(struint ret;/* get encoder from crtc */ -drm_for_each_encoder (encoder, ddev) -if (encoder->crtc == crtc) +drm_for_each_encoder (en_iter, ddev) +if (en_iter->crtc == crtc) { + encoder = en_iter;break ; + }if (encoder) {/* get bridge from encoder */ -list_for_each_entry (bridge, &encoder->bridge_chain, chain_node) -if (bridge->encoder == encoder) +list_for_each_entry (br_iter, &encoder->bridge_chain, chain_node) +if (br_iter->encoder == encoder) { + bridge = br_iter;break ; + }/* Get the connector from encoder */ drm_connector_list_iter_begin (ddev, &iter);
Greg Kroah-Hartman
maintainerPATCH 839/879 bcache: improve multithreaded bch_btree_check()
In reply to Greg Kroah-HartmanFrom: Coly Li <[email protected]>
commit 622536443b6731ec82c563aae7807165adbe9178 upstream.
Commit 8e7102273f59 ("bcache: make bch_btree_check() to be multithreaded") makes bch_btree_check() to be much faster when checking all btree nodes during cache device registration. But it isn't in ideal shap yet, still can be improved.
This patch does the following thing to improve current parallel btree nodes check by multiple threads in bch_btree_check(),
- Add read lock to root node while checking all the btree nodes with multiple threads. Although currently it is not mandatory but it is good to have a read lock in code logic.
- Remove local variable 'char name[32]', and generate kernel thread name string directly when calling kthread_run().
- Allocate local variable "struct btree_check_state check_state" on the stack and avoid unnecessary dynamic memory allocation for it.
- Reduce BCH_BTR_CHKTHREAD_MAX from 64 to 12 which is enough indeed.
- Increase check_state->started to count created kernel thread after it succeeds to create.
- When wait for all checking kernel threads to finish, use wait_event() to replace wait_event_interruptible().
With this change, the code is more clear, and some potential error conditions are avoided.
--- drivers/md/bcache/btree.c | 58 ++++++++++++++++++++-------------------------- drivers/md/bcache/btree.h | 2 - 2 files changed, 27 insertions(+), 33 deletions(-)
drivers/md/bcache/btree.c +26 -32
@@ -2006,8 +2006,7 @@ int bch_btree_check(struct cache_set *c)int i;struct bkey *k =NULL ;struct btree_iter iter; -struct btree_check_state *check_state; -char name[32 ]; +struct btree_check_state check_state;/* check and mark root node keys */ for_each_key_filter (&c->root->keys, k, &iter, bch_ptr_invalid)
@@ -2018,63 +2017,58 @@ int bch_btree_check(struct cache_set *c)if (c->root->level ==0 )return 0 ; - check_state =kzalloc (sizeof (struct btree_check_state ),GFP_KERNEL ); -if (!check_state) -return -ENOMEM ; - - check_state->c = c; - check_state->total_threads =bch_btree_chkthread_nr (); - check_state->key_idx =0 ; -spin_lock_init (&check_state->idx_lock); -atomic_set (&check_state->started,0 ); -atomic_set (&check_state->enough,0 ); -init_waitqueue_head (&check_state->wait); + check_state.c = c; + check_state.total_threads =bch_btree_chkthread_nr (); + check_state.key_idx =0 ; +spin_lock_init (&check_state.idx_lock); +atomic_set (&check_state.started,0 ); +atomic_set (&check_state.enough,0 ); +init_waitqueue_head (&check_state.wait); +rw_lock (0 , c->root, c->root->level);/* * Run multiple threads to check btree nodes in parallel, -* if check_state->enough is non-zero, it means current +* if check_state.enough is non-zero, it means current * running check threads are enough, unncessary to create * more. */ -for (i =0 ; i < check_state->total_threads; i++) { -/* fetch latest check_state->enough earlier */ +for (i =0 ; i < check_state.total_threads; i++) { +/* fetch latest check_state.enough earlier */ smp_mb__before_atomic (); -if (atomic_read (&check_state->enough)) +if (atomic_read (&check_state.enough))break ; - check_state->infos[i].result =0 ; - check_state->infos[i].state = check_state; -snprintf (name,sizeof (name),"bch_btrchk[%u]" , i); -atomic_inc (&check_state->started); + check_state.infos[i].result =0 ; + check_state.infos[i].state = &check_state; - check_state->infos[i].thread = + check_state.infos[i].thread =kthread_run (bch_btree_check_thread, - &check_state->infos[i], - name); -if (IS_ERR (check_state->infos[i].thread)) { + &check_state.infos[i], +"bch_btrchk[%d]" , i); +if (IS_ERR (check_state.infos[i].thread)) {pr_err ("fails to run thread bch_btrchk[%d]\n" , i);for (--i; i >=0 ; i--) -kthread_stop (check_state->infos[i].thread); +kthread_stop (check_state.infos[i].thread); ret = -ENOMEM ; goto out; } +atomic_inc (&check_state.started); }/* * Must wait for all threads to stop. */ -wait_event_interruptible (check_state->wait, -atomic_read (&check_state->started) ==0 ); +wait_event (check_state.wait,atomic_read (&check_state.started) ==0 ); -for (i =0 ; i < check_state->total_threads; i++) { -if (check_state->infos[i].result) { - ret = check_state->infos[i].result; +for (i =0 ; i < check_state.total_threads; i++) { +if (check_state.infos[i].result) { + ret = check_state.infos[i].result; goto out; } } out: -kfree (check_state); +rw_unlock (0 , c->root);return ret; }
drivers/md/bcache/btree.h +1 -1
@@ -226,7 +226,7 @@ struct btree_check_info {int result; }; -#define BCH_BTR_CHKTHREAD_MAX 64 +#define BCH_BTR_CHKTHREAD_MAX 12struct btree_check_state {struct cache_set *c;int total_threads;
Greg Kroah-Hartman
maintainerPATCH 840/879 bcache: improve multithreaded bch_sectors_dirty_init()
In reply to Greg Kroah-HartmanFrom: Coly Li <[email protected]>
commit 4dc34ae1b45fe26e772a44379f936c72623dd407 upstream.
Commit b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") makes bch_sectors_dirty_init() to be much faster when counting dirty sectors by iterating all dirty keys in the btree. But it isn't in ideal shape yet, still can be improved.
This patch does the following changes to improve current parallel dirty keys iteration on the btree,
- Add read lock to root node when multiple threads iterating the btree, to prevent the root node gets split by I/Os from other registered bcache devices.
- Remove local variable "char name[32]" and generate kernel thread name string directly when calling kthread_run().
- Allocate "struct bch_dirty_init_state state" directly on stack and avoid the unnecessary dynamic memory allocation for it.
- Decrease BCH_DIRTY_INIT_THRD_MAX from 64 to 12 which is enough indeed.
- Increase &state->started to count created kernel thread after it succeeds to create.
- When wait for all dirty key counting threads to finish, use wait_event() to replace wait_event_interruptible().
With the above changes, the code is more clear, and some potential error conditions are avoided.
--- drivers/md/bcache/writeback.c | 60 ++++++++++++++++-------------------------- drivers/md/bcache/writeback.h | 2 - 2 files changed, 25 insertions(+), 37 deletions(-)
drivers/md/bcache/writeback.c +24 -36
@@ -948,10 +948,10 @@ void bch_sectors_dirty_init(struct bcachstruct btree_iter iter;struct sectors_dirty_init op;struct cache_set *c = d->c; -struct bch_dirty_init_state *state; -char name[32 ]; +struct bch_dirty_init_state state;/* Just count root keys if no leaf node */ +rw_lock (0 , c->root, c->root->level);if (c->root->level ==0 ) {bch_btree_op_init (&op.op,-1 ); op.inode = d->id;
@@ -961,54 +961,42 @@ void bch_sectors_dirty_init(struct bcachfor_each_key_filter (&c->root->keys, k, &iter, bch_ptr_invalid)sectors_dirty_init_fn (&op.op, c->root, k); +rw_unlock (0 , c->root);return ; } - state =kzalloc (sizeof (struct bch_dirty_init_state ),GFP_KERNEL ); -if (!state) { -pr_warn ("sectors dirty init failed: cannot allocate memory\n" ); -return ; - } + state.c = c; + state.d = d; + state.total_threads =bch_btre_dirty_init_thread_nr (); + state.key_idx =0 ; +spin_lock_init (&state.idx_lock); +atomic_set (&state.started,0 ); +atomic_set (&state.enough,0 ); +init_waitqueue_head (&state.wait); - state->c = c; - state->d = d; - state->total_threads =bch_btre_dirty_init_thread_nr (); - state->key_idx =0 ; -spin_lock_init (&state->idx_lock); -atomic_set (&state->started,0 ); -atomic_set (&state->enough,0 ); -init_waitqueue_head (&state->wait); - -for (i =0 ; i < state->total_threads; i++) { -/* Fetch latest state->enough earlier */ +for (i =0 ; i < state.total_threads; i++) { +/* Fetch latest state.enough earlier */ smp_mb__before_atomic (); -if (atomic_read (&state->enough)) +if (atomic_read (&state.enough))break ; - state->infos[i].state = state; -atomic_inc (&state->started); -snprintf (name,sizeof (name),"bch_dirty_init[%d]" , i); - - state->infos[i].thread = -kthread_run (bch_dirty_init_thread, - &state->infos[i], - name); -if (IS_ERR (state->infos[i].thread)) { + state.infos[i].state = &state; + state.infos[i].thread = +kthread_run (bch_dirty_init_thread, &state.infos[i], +"bch_dirtcnt[%d]" , i); +if (IS_ERR (state.infos[i].thread)) {pr_err ("fails to run thread bch_dirty_init[%d]\n" , i);for (--i; i >=0 ; i--) -kthread_stop (state->infos[i].thread); +kthread_stop (state.infos[i].thread); goto out; } +atomic_inc (&state.started); } -/* -* Must wait for all threads to stop. -*/ -wait_event_interruptible (state->wait, -atomic_read (&state->started) ==0 ); - out: -kfree (state); +/* Must wait for all threads to stop. */ +wait_event (state.wait,atomic_read (&state.started) ==0 ); +rw_unlock (0 , c->root); }void bch_cached_dev_writeback_init (struct cached_dev *dc)
drivers/md/bcache/writeback.h +1 -1
@@ -20,7 +20,7 @@#define BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID 57#define BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH 64 -#define BCH_DIRTY_INIT_THRD_MAX 64 +#define BCH_DIRTY_INIT_THRD_MAX 12/* * 14 (16384ths) is chosen here as something that each backing device * should be a reasonable fraction of the share, and not to blow up
Greg Kroah-Hartman
maintainerPATCH 841/879 bcache: remove incremental dirty sector counting for bch_sectors_dirty_init()
In reply to Greg Kroah-HartmanFrom: Coly Li <[email protected]>
commit 80db4e4707e78cb22287da7d058d7274bd4cb370 upstream.
After making bch_sectors_dirty_init() being multithreaded, the existing incremental dirty sector counting in bch_root_node_dirty_init() doesn't release btree occupation after iterating 500000 (INIT_KEYS_EACH_TIME) bkeys. Because a read lock is added on btree root node to prevent the btree to be split during the dirty sectors counting, other I/O requester has no chance to gain the write lock even restart bcache_btree().
That is to say, the incremental dirty sectors counting is incompatible to the multhreaded bch_sectors_dirty_init(). We have to choose one and drop another one.
In my testing, with 512 bytes random writes, I generate 1.2T dirty data and a btree with 400K nodes. With single thread and incremental dirty sectors counting, it takes 30+ minites to register the backing device. And with multithreaded dirty sectors counting, the backing device registration can be accomplished within 2 minutes.
The 30+ minutes V.S. 2- minutes difference makes me decide to keep multithreaded bch_sectors_dirty_init() and drop the incremental dirty sectors counting. This is what this patch does.
But INIT_KEYS_EACH_TIME is kept, in sectors_dirty_init_fn() the CPU will be released by cond_resched() after every INIT_KEYS_EACH_TIME keys iterated. This is to avoid the watchdog reports a bogus soft lockup warning.
--- drivers/md/bcache/writeback.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-)
drivers/md/bcache/writeback.c +12 -27
@@ -805,13 +805,11 @@ static int bch_writeback_thread(void *ar/* Init */ #define INIT_KEYS_EACH_TIME 500000 -#define INIT_KEYS_SLEEP_MS 100struct sectors_dirty_init {struct btree_op op;unsigned int inode;size_t count; -struct bkey start; }; static int sectors_dirty_init_fn(struct btree_op *_op, struct btree *b,
@@ -827,11 +825,8 @@ static int sectors_dirty_init_fn(struct KEY_START(k), KEY_SIZE(k)); op->count++; -if (atomic_read (&b->c->search_inflight) && - !(op->count %INIT_KEYS_EACH_TIME )) { -bkey_copy_key (&op->start, k); -return -EAGAIN ; - } +if (!(op->count %INIT_KEYS_EACH_TIME )) +cond_resched ();return MAP_CONTINUE ; }
@@ -846,24 +841,16 @@ static int bch_root_node_dirty_init(strubch_btree_op_init (&op.op,-1 ); op.inode = d->id; op.count =0 ; - op.start =KEY (op.inode,0 ,0 ); -do { - ret =bcache_btree (map_keys_recurse, - k, - c->root, - &op.op, - &op.start, - sectors_dirty_init_fn, -0 ); -if (ret == -EAGAIN ) -schedule_timeout_interruptible ( -msecs_to_jiffies (INIT_KEYS_SLEEP_MS )); -else if (ret <0 ) { -pr_warn ("sectors dirty init failed, ret=%d!\n" , ret); -break ; - } - }while (ret == -EAGAIN ); + ret =bcache_btree (map_keys_recurse, + k, + c->root, + &op.op, + &KEY (op.inode,0 ,0 ), + sectors_dirty_init_fn, +0 ); +if (ret <0 ) +pr_warn ("sectors dirty init failed, ret=%d!\n" , ret);return ret; }
@@ -907,7 +894,6 @@ static int bch_dirty_init_thread(void *a goto out; } skip_nr--; -cond_resched (); }if (p) {
@@ -917,7 +903,6 @@ static int bch_dirty_init_thread(void *a p =NULL ; prev_idx = cur_idx; -cond_resched (); } out:
@@ -956,11 +941,11 @@ void bch_sectors_dirty_init(struct bcachbch_btree_op_init (&op.op,-1 ); op.inode = d->id; op.count =0 ; - op.start =KEY (op.inode,0 ,0 );for_each_key_filter (&c->root->keys, k, &iter, bch_ptr_invalid)sectors_dirty_init_fn (&op.op, c->root, k); +rw_unlock (0 , c->root);return ; }
Greg Kroah-Hartman
maintainerPATCH 842/879 bcache: avoid journal no-space deadlock by reserving 1 journal bucket
In reply to Greg Kroah-HartmanFrom: Coly Li <[email protected]>
commit 32feee36c30ea06e38ccb8ae6e5c44c6eec790a6 upstream.
The journal no-space deadlock was reported time to time. Such deadlock can happen in the following situation.
When all journal buckets are fully filled by active jset with heavy write I/O load, the cache set registration (after a reboot) will load all active jsets and inserting them into the btree again (which is called journal replay). If a journaled bkey is inserted into a btree node and results btree node split, new journal request might be triggered. For example, the btree grows one more level after the node split, then the root node record in cache device super block will be upgrade by bch_journal_meta() from bch_btree_set_root(). But there is no space in journal buckets, the journal replay has to wait for new journal bucket to be reclaimed after at least one journal bucket replayed. This is one example that how the journal no-space deadlock happens.
The solution to avoid the deadlock is to reserve 1 journal bucket in run time, and only permit the reserved journal bucket to be used during cache set registration procedure for things like journal replay. Then the journal space will never be fully filled, there is no chance for journal no-space deadlock to happen anymore.
This patch adds a new member "bool do_reserve" in struct journal, it is inititalized to 0 (false) when struct journal is allocated, and set to 1 (true) by bch_journal_space_reserve() when all initialization done in run_cache_set(). In the run time when journal_reclaim() tries to allocate a new journal bucket, free_journal_buckets() is called to check whether there are enough free journal buckets to use. If there is only 1 free journal bucket and journal->do_reserve is 1 (true), the last bucket is reserved and free_journal_buckets() will return 0 to indicate no free journal bucket. Then journal_reclaim() will give up, and try next time to see whetheer there is free journal bucket to allocate. By this method, there is always 1 jouranl bucket reserved in run time.
During the cache set registration, journal->do_reserve is 0 (false), so the reserved journal bucket can be used to avoid the no-space deadlock.
--- drivers/md/bcache/journal.c | 31 ++++++++++++++++++++++++++----- drivers/md/bcache/journal.h | 2 ++ drivers/md/bcache/super.c | 1 + 3 files changed, 29 insertions(+), 5 deletions(-)
drivers/md/bcache/journal.c +26 -5
@@ -405,6 +405,11 @@ err:return ret; } +void bch_journal_space_reserve (struct journal *j) +{ + j->do_reserve = true; +} +/* Journalling */ static void btree_flush_write (struct cache_set *c)
@@ -621,12 +626,30 @@ static void do_journal_discard(struct ca } } +static unsigned int free_journal_buckets (struct cache_set *c) +{ +struct journal *j = &c->journal; +struct cache *ca = c->cache; +struct journal_device *ja = &c->cache->journal; +unsigned int n; + +/* In case njournal_buckets is not power of 2 */ +if (ja->cur_idx >= ja->discard_idx) + n = ca->sb.njournal_buckets + ja->discard_idx - ja->cur_idx; +else + n = ja->discard_idx - ja->cur_idx; + +if (n > (1 + j->do_reserve)) +return n - (1 + j->do_reserve); + +return 0 ; +} +static void journal_reclaim (struct cache_set *c) {struct bkey *k = &c->journal.key;struct cache *ca = c->cache;uint64_t last_seq; -unsigned int next;struct journal_device *ja = &ca->journal;atomic_t p__maybe_unused ;
@@ -649,12 +672,10 @@ static void journal_reclaim(struct cacheif (c->journal.blocks_free) goto out; - next = (ja->cur_idx +1 ) % ca->sb.njournal_buckets; -/* No space available on this device */ -if (next == ja->discard_idx) +if (!free_journal_buckets (c)) goto out; - ja->cur_idx = next; + ja->cur_idx = (ja->cur_idx +1 ) % ca->sb.njournal_buckets; k->ptr[0 ] =MAKE_PTR (0 ,bucket_to_sector (c, ca->sb.d[ja->cur_idx]), ca->sb.nr_this_dev);
drivers/md/bcache/journal.h +2 -0
@@ -105,6 +105,7 @@ struct journal {spinlock_t lock;spinlock_t flush_write_lock;bool btree_flushing; +bool do_reserve;/* used when waiting because the journal was full */ struct closure_waitlist wait;struct closure io;
@@ -182,5 +183,6 @@ int bch_journal_replay(struct cache_setvoid bch_journal_free (struct cache_set *c);int bch_journal_alloc (struct cache_set *c); +void bch_journal_space_reserve (struct journal *j);#endif /* _BCACHE_JOURNAL_H */
drivers/md/bcache/super.c +1 -0
@@ -2128,6 +2128,7 @@ static int run_cache_set(struct cache_seflash_devs_run (c); +bch_journal_space_reserve (&c->journal);set_bit (CACHE_SET_RUNNING , &c->flags);return 0 ; err:
Greg Kroah-Hartman
maintainerPATCH 843/879 serial: pch: dont overwrite xmit->buf[0] by x_char
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit d9f3af4fbb1d955bbaf872d9e76502f6e3e803cb upstream.
When x_char is to be sent, the TX path overwrites whatever is in the circular buffer at offset 0 with x_char and sends it using pch_uart_hal_write(). I don't understand how this was supposed to work if xmit->buf[0] already contained some character. It must have been lost.
Remove this whole pop_tx_x() concept and do the work directly in the callers. (Without printing anything using dev_dbg().)
--- drivers/tty/serial/pch_uart.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-)
drivers/tty/serial/pch_uart.c +7 -20
@@ -624,22 +624,6 @@ static int push_rx(struct eg20t_port *prreturn 0 ; } -static int pop_tx_x (struct eg20t_port *priv,unsigned char *buf) -{ -int ret =0 ; -struct uart_port *port = &priv->port; - -if (port->x_char) { -dev_dbg (priv->port.dev,"%s:X character send %02x (%lu)\n" , - __func__, port->x_char, jiffies); - buf[0 ] = port->x_char; - port->x_char =0 ; - ret =1 ; - } - -return ret; -} -static int dma_push_rx (struct eg20t_port *priv,int size) {int room;
@@ -889,9 +873,10 @@ static unsigned int handle_tx(struct eg2 fifo_size =max (priv->fifo_size,1 ); tx_empty =1 ; -if (pop_tx_x (priv, xmit->buf)) { -pch_uart_hal_write (priv, xmit->buf,1 ); +if (port->x_char) { +pch_uart_hal_write (priv, &port->x_char,1 ); port->icount.tx++; + port->x_char =0 ; tx_empty =0 ; fifo_size--; }
@@ -946,9 +931,11 @@ static unsigned int dma_handle_tx(struct } fifo_size =max (priv->fifo_size,1 ); -if (pop_tx_x (priv, xmit->buf)) { -pch_uart_hal_write (priv, xmit->buf,1 ); + +if (port->x_char) { +pch_uart_hal_write (priv, &port->x_char,1 ); port->icount.tx++; + port->x_char =0 ; fifo_size--; }
Greg Kroah-Hartman
maintainerPATCH 844/879 tilcdc: tilcdc_external: fix an incorrect NULL check on list iterator
In reply to Greg Kroah-HartmanFrom: Xiaomeng Tong <[email protected]>
commit 8b917cbe38e9b0d002492477a9fc2bfee2412ce4 upstream.
The bug is here:
if (!encoder) {The list iterator value 'encoder' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found.
To fix the bug, use a new variable 'iter' as the list iterator, while use the original variable 'encoder' as a dedicated pointer to point to the found element.
--- drivers/gpu/drm/tilcdc/tilcdc_external.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/gpu/drm/tilcdc/tilcdc_external.c +5 -3
@@ -60,11 +60,13 @@ struct drm_connector *tilcdc_encoder_finint tilcdc_add_component_encoder (struct drm_device *ddev) {struct tilcdc_drm_private *priv = ddev->dev_private; -struct drm_encoder *encoder; +struct drm_encoder *encoder =NULL , *iter; -list_for_each_entry (encoder, &ddev->mode_config.encoder_list, head) -if (encoder->possible_crtcs & (1 << priv->crtc->index)) +list_for_each_entry (iter, &ddev->mode_config.encoder_list, head) +if (iter->possible_crtcs & (1 << priv->crtc->index)) { + encoder = iter;break ; + }if (!encoder) {dev_err (ddev->dev,"%s: No suitable encoder found\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 845/879 gma500: fix an incorrect NULL check on list iterator
In reply to Greg Kroah-HartmanFrom: Xiaomeng Tong <[email protected]>
commit bdef417d84536715145f6dc9cc3275c46f26295a upstream.
The bug is here:
return crtc;
The list iterator value 'crtc' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found.
To fix the bug, return 'crtc' when found, otherwise return NULL.
--- drivers/gpu/drm/gma500/psb_intel_display.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/gma500/psb_intel_display.c +4 -3
@@ -535,14 +535,15 @@ void psb_intel_crtc_init(struct drm_devistruct drm_crtc *psb_intel_get_crtc_from_pipe (struct drm_device *dev,int pipe) { -struct drm_crtc *crtc =NULL ; +struct drm_crtc *crtc;list_for_each_entry (crtc, &dev->mode_config.crtc_list, head) {struct gma_crtc *gma_crtc =to_gma_crtc (crtc); +if (gma_crtc->pipe == pipe) -break ; +return crtc; } -return crtc; +return NULL ; }int gma_connector_clones (struct drm_device *dev,int type_mask)
Greg Kroah-Hartman
maintainerPATCH 846/879 arm64: dts: qcom: ipq8074: fix the sleep clock frequency
In reply to Greg Kroah-HartmanFrom: Kathiravan T <[email protected]>
commit f607dd767f5d6800ffbdce5b99ba81763b023781 upstream.
Sleep clock frequency should be 32768Hz. Lets fix it.
--- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq8074.dtsi +1 -1
@@ -13,7 +13,7 @@ clocks { sleep_clk: sleep_clk { compatible = "fixed-clock"; - clock-frequency = <32000>; + clock-frequency = <32768>; #clock-cells = <0>; };
Greg Kroah-Hartman
maintainerPATCH 847/879 arm64: tegra: Add missing DFLL reset on Tegra210
In reply to Greg Kroah-HartmanFrom: Diogo Ivo <[email protected]>
commit 0017f2c856e21bb900be88469e15dac4f41f4065 upstream.
Commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") removed deassertion of reset lines when enabling peripheral clocks. This breaks the initialization of the DFLL driver which relied on this behaviour.
In order to be able to fix this, add the corresponding reset to the DT. Tested on Google Pixel C.
--- arch/arm64/boot/dts/nvidia/tegra210.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/nvidia/tegra210.dtsi +3 -2
@@ -1366,8 +1366,9 @@ <&tegra_car TEGRA210_CLK_DFLL_REF>, <&tegra_car TEGRA210_CLK_I2C5>; clock-names = "soc", "ref", "i2c"; - resets = <&tegra_car TEGRA210_RST_DFLL_DVCO>; - reset-names = "dvco"; + resets = <&tegra_car TEGRA210_RST_DFLL_DVCO>, + <&tegra_car 155>; + reset-names = "dvco", "dfll"; #clock-cells = <0>; clock-output-names = "dfllCPU_out"; status = "disabled";
Greg Kroah-Hartman
maintainerPATCH 848/879 clk: tegra: Add missing reset deassertion
In reply to Greg Kroah-HartmanFrom: Diogo Ivo <[email protected]>
commit 23a43cc437e747473d5f8f98b4fe189fb5c433b7 upstream.
Commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") removed deassertion of reset lines when enabling peripheral clocks. This breaks the initialization of the DFLL driver which relied on this behaviour.
Fix this problem by adding explicit deassert/assert requests to the driver. Tested on Google Pixel C.
--- drivers/clk/tegra/clk-dfll.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/clk/tegra/clk-dfll.c +12 -0
@@ -271,6 +271,7 @@ struct tegra_dfll {struct clk *ref_clk;struct clk *i2c_clk;struct clk *dfll_clk; +struct reset_control *dfll_rst;struct reset_control *dvco_rst;unsigned long ref_rate;unsigned long i2c_clk_rate;
@@ -1464,6 +1465,7 @@ static int dfll_init(struct tegra_dfll *return -EINVAL ; } +reset_control_deassert (td->dfll_rst);reset_control_deassert (td->dvco_rst); ret =clk_prepare (td->ref_clk);
@@ -1509,6 +1511,7 @@ di_err1:clk_unprepare (td->ref_clk);reset_control_assert (td->dvco_rst); +reset_control_assert (td->dfll_rst);return ret; }
@@ -1530,6 +1533,7 @@ int tegra_dfll_suspend(struct device *de }reset_control_assert (td->dvco_rst); +reset_control_assert (td->dfll_rst);return 0 ; }
@@ -1548,6 +1552,7 @@ int tegra_dfll_resume(struct device *dev {struct tegra_dfll *td =dev_get_drvdata (dev); +reset_control_deassert (td->dfll_rst);reset_control_deassert (td->dvco_rst);pm_runtime_get_sync (td->dev);
@@ -1951,6 +1956,12 @@ int tegra_dfll_register(struct platform_ td->soc = soc; + td->dfll_rst =devm_reset_control_get_optional (td->dev,"dfll" ); +if (IS_ERR (td->dfll_rst)) { +dev_err (td->dev,"couldn't get dfll reset\n" ); +return PTR_ERR (td->dfll_rst); + } + td->dvco_rst =devm_reset_control_get (td->dev,"dvco" );if (IS_ERR (td->dvco_rst)) {dev_err (td->dev,"couldn't get dvco reset\n" );
@@ -2087,6 +2098,7 @@ struct tegra_dfll_soc_data *tegra_dfll_uclk_unprepare (td->i2c_clk);reset_control_assert (td->dvco_rst); +reset_control_assert (td->dfll_rst);return td->soc; }
Greg Kroah-Hartman
maintainerPATCH 849/879 phy: qcom-qmp: fix struct clk leak on probe errors
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit f0a4bc38a12f5a0cc5ad68670d9480e91e6a94df upstream.
Make sure to release the pipe clock reference in case of a late probe error (e.g. probe deferral).
--- drivers/phy/qualcomm/phy-qcom-qmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/qualcomm/phy-qcom-qmp.c +1 -1
@@ -5890,7 +5890,7 @@ int qcom_qmp_phy_create(struct device *d* all phys that don't need this. */ snprintf (prop_name,sizeof (prop_name),"pipe%d" , id); - qphy->pipe_clk =of_clk_get_by_name (np, prop_name); + qphy->pipe_clk =devm_get_clk_from_child (dev, np, prop_name);if (IS_ERR (qphy->pipe_clk)) {if (cfg->type ==PHY_TYPE_PCIE || cfg->type ==PHY_TYPE_USB3 ) {
Greg Kroah-Hartman
maintainerPATCH 850/879 ARM: dts: s5pv210: Remove spi-cs-high on panel in Aries
In reply to Greg Kroah-HartmanFrom: Jonathan Bakker <[email protected]>
commit 096f58507374e1293a9e9cff8a1ccd5f37780a20 upstream.
Since commit 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors"), the panel has been blank due to an inverted CS GPIO. In order to correct this, drop the spi-cs-high from the panel SPI device.
--- arch/arm/boot/dts/s5pv210-aries.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm/boot/dts/s5pv210-aries.dtsi +0 -1
@@ -564,7 +564,6 @@ reset-gpios = <&mp05 5 GPIO_ACTIVE_LOW>; vdd3-supply = <&ldo7_reg>; vci-supply = <&ldo17_reg>; - spi-cs-high; spi-max-frequency = <1200000>; pinctrl-names = "default";
Greg Kroah-Hartman
maintainerPATCH 851/879 ARM: pxa: maybe fix gpio lookup tables
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit 2672a4bff6c03a20d5ae460a091f67ee782c3eff upstream.
Quoted 1 line
From inspection I found a couple of GPIO lookups that are
listed with device "gpio-pxa", but actually have a number from a different gpio controller.
Try to rectify that here, with a guess of what the actual device name is.
--- arch/arm/mach-pxa/cm-x300.c | 8 ++++---- arch/arm/mach-pxa/magician.c | 2 +- arch/arm/mach-pxa/tosa.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-)
arch/arm/mach-pxa/cm-x300.c +4 -4
@@ -354,13 +354,13 @@ static struct platform_device cm_x300_spstatic struct gpiod_lookup_table cm_x300_spi_gpiod_table = { .dev_id ="spi_gpio" , .table = { -GPIO_LOOKUP ("gpio-pxa" ,GPIO_LCD_SCL , +GPIO_LOOKUP ("pca9555.1" ,GPIO_LCD_SCL -GPIO_LCD_BASE ,"sck" ,GPIO_ACTIVE_HIGH ), -GPIO_LOOKUP ("gpio-pxa" ,GPIO_LCD_DIN , +GPIO_LOOKUP ("pca9555.1" ,GPIO_LCD_DIN -GPIO_LCD_BASE ,"mosi" ,GPIO_ACTIVE_HIGH ), -GPIO_LOOKUP ("gpio-pxa" ,GPIO_LCD_DOUT , +GPIO_LOOKUP ("pca9555.1" ,GPIO_LCD_DOUT -GPIO_LCD_BASE ,"miso" ,GPIO_ACTIVE_HIGH ), -GPIO_LOOKUP ("gpio-pxa" ,GPIO_LCD_CS , +GPIO_LOOKUP ("pca9555.1" ,GPIO_LCD_CS -GPIO_LCD_BASE ,"cs" ,GPIO_ACTIVE_HIGH ), { }, },
arch/arm/mach-pxa/magician.c +1 -1
@@ -681,7 +681,7 @@ static struct platform_device bq24022 =static struct gpiod_lookup_table bq24022_gpiod_table = { .dev_id ="gpio-regulator" , .table = { -GPIO_LOOKUP ("gpio-pxa" ,EGPIO_MAGICIAN_BQ24022_ISET2 , +GPIO_LOOKUP ("htc-egpio-0" ,EGPIO_MAGICIAN_BQ24022_ISET2 -MAGICIAN_EGPIO_BASE ,NULL ,GPIO_ACTIVE_HIGH ),GPIO_LOOKUP ("gpio-pxa" , GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,"enable" ,GPIO_ACTIVE_LOW ),
arch/arm/mach-pxa/tosa.c +2 -2
@@ -296,9 +296,9 @@ static struct gpiod_lookup_table tosa_mc .table = {GPIO_LOOKUP ("gpio-pxa" , TOSA_GPIO_nSD_DETECT,"cd" ,GPIO_ACTIVE_LOW ), -GPIO_LOOKUP ("gpio-pxa" ,TOSA_GPIO_SD_WP , +GPIO_LOOKUP ("sharp-scoop.0" ,TOSA_GPIO_SD_WP -TOSA_SCOOP_GPIO_BASE ,"wp" ,GPIO_ACTIVE_LOW ), -GPIO_LOOKUP ("gpio-pxa" ,TOSA_GPIO_PWR_ON , +GPIO_LOOKUP ("sharp-scoop.0" ,TOSA_GPIO_PWR_ON -TOSA_SCOOP_GPIO_BASE , "power", GPIO_ACTIVE_HIGH), { }, },
Greg Kroah-Hartman
maintainerPATCH 852/879 ceph: fix decoding of client session messages flags
In reply to Greg Kroah-HartmanFrom: Luís Henriques <[email protected]>
commit ea16567f11018e2f58e72b667b0c803ff92b8153 upstream.
The cephfs kernel client started to show the message:
ceph: mds0 session blocklisted
when mounting a filesystem. This is due to the fact that the session messages are being incorrectly decoded: the skip needs to take into account the 'len'.
While there, fixed some whitespaces too.
--- fs/ceph/mds_client.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
fs/ceph/mds_client.c +9 -5
@@ -3375,13 +3375,17 @@ static void handle_session(struct ceph_m }if (msg_version >=5 ) { -u32 flags; -/* version >= 4, struct_v, struct_cv, len, metric_spec */ -ceph_decode_skip_n (&p, end,2 +sizeof (u32) *2 , bad); +u32 flags, len; + +/* version >= 4 */ +ceph_decode_skip_16 (&p, end, bad);/* struct_v, struct_cv */ +ceph_decode_32_safe (&p, end, len, bad);/* len */ +ceph_decode_skip_n (&p, end, len, bad);/* metric_spec */ +/* version >= 5, flags */ -ceph_decode_32_safe (&p, end, flags, bad); +ceph_decode_32_safe (&p, end, flags, bad);if (flags &CEPH_SESSION_BLOCKLISTED ) { -pr_warn ("mds%d session blocklisted\n" , session->s_mds); +pr_warn ("mds%d session blocklisted\n" , session->s_mds); blocklisted = true; } }
Greg Kroah-Hartman
maintainerPATCH 853/879 misc: fastrpc: fix list iterator in fastrpc_req_mem_unmap_impl
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
commit c5c07c5958cf0c9af6e76813e6de15d42ee49822 upstream.
This is another instance of incorrect use of list iterator and checking it for NULL.
The list iterator value 'map' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty (in this case, the check 'if (!map) {' will always be false and never exit as expected).
To fix the bug, use a new variable 'iter' as the list iterator, while use the original variable 'map' as a dedicated pointer to point to the found element.
Without this patch, Kernel crashes with below trace:
Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000ffff7fb03750 ... Call trace: fastrpc_map_create+0x70/0x290 [fastrpc] fastrpc_req_mem_map+0xf0/0x2dc [fastrpc] fastrpc_device_ioctl+0x138/0xc60 [fastrpc] __arm64_sys_ioctl+0xa8/0xec invoke_syscall+0x48/0x114 el0_svc_common.constprop.0+0xd4/0xfc do_el0_svc+0x28/0x90 el0_svc+0x3c/0x130 el0t_64_sync_handler+0xa4/0x130 el0t_64_sync+0x18c/0x190 Code: 14000016 f94000a5 eb05029f 54000260 (b94018a6) ---[ end trace 0000000000000000 ]---
--- drivers/misc/fastrpc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/misc/fastrpc.c +5 -4
@@ -1747,17 +1747,18 @@ err_invoke:static int fastrpc_req_mem_unmap_impl (struct fastrpc_user *fl,struct fastrpc_mem_unmap *req) {struct fastrpc_invoke_args args[1 ] = { [0 ] = {0 } }; -struct fastrpc_map *map =NULL , *m; +struct fastrpc_map *map =NULL , *iter, *m;struct fastrpc_mem_unmap_req_msg req_msg = {0 };int err =0 ;u32 sc;struct device *dev = fl->sctx->dev;spin_lock (&fl->lock); -list_for_each_entry_safe (map, m, &fl->maps, node) { -if ((req->fd <0 || map->fd == req->fd) && (map->raddr == req->vaddr)) +list_for_each_entry_safe (iter, m, &fl->maps, node) { +if ((req->fd <0 || iter->fd == req->fd) && (iter->raddr == req->vaddr)) { + map = iter;break ; - map =NULL ; + } }spin_unlock (&fl->lock);
Greg Kroah-Hartman
maintainerPATCH 854/879 SMB3: EBADF/EIO errors in rename/open caused by race condition in smb2_compound_op
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit 0a55cf74ffb5d004b93647e4389096880ce37d6b upstream.
There is a race condition in smb2_compound_op:
after_close:
num_rqst++;
if (cfile) {
cifsFileInfo_put(cfile); // sends SMB2_CLOSE to the server
cfile = NULL;This is triggered by smb2_query_path_info operation that happens during revalidate_dentry. In smb2_query_path_info, get_readable_path is called to load the cfile, increasing the reference counter. If in the meantime, this reference becomes the very last, this call to cifsFileInfo_put(cfile) will trigger a SMB2_CLOSE request sent to the server just before sending this compound request – and so then the compound request fails either with EBADF/EIO depending on the timing at the server, because the handle is already closed.
In the first scenario, the race seems to be happening between smb2_query_path_info triggered by the rename operation, and between “cleanup” of asynchronous writes – while fsync(fd) likely waits for the asynchronous writes to complete, releasing the writeback structures can happen after the close(fd) call. So the EBADF/EIO errors will pop up if the timing is such that:
1) There are still outstanding references after close(fd) in the writeback structures
2) smb2_query_path_info successfully fetches the cfile, increasing the refcounter by 1
3) All writeback structures release the same cfile, reducing refcounter to 1
4) smb2_compound_op is called with that cfile
In the second scenario, the race seems to be similar – here open triggers the smb2_query_path_info operation, and if all other threads in the meantime decrease the refcounter to 1 similarly to the first scenario, again SMB2_CLOSE will be sent to the server just before issuing the compound request. This case is harder to reproduce.
See https://bugzilla.samba.org/show_bug.cgi?id=15051
--- fs/cifs/smb2inode.c | 2 -- 1 file changed, 2 deletions(-)
fs/cifs/smb2inode.c +0 -2
@@ -362,8 +362,6 @@ smb2_compound_op(const unsigned int xid, num_rqst++;if (cfile) { -cifsFileInfo_put (cfile); - cfile =NULL ; rc = compound_send_recv(xid, ses, server, flags, num_rqst - 2, &rqst[1], &resp_buftype[1],
Greg Kroah-Hartman
maintainerPATCH 855/879 docs/conf.py: Cope with removal of language=None in Sphinx 5.0.0
In reply to Greg Kroah-HartmanFrom: Akira Yokosawa <[email protected]>
commit 627f01eab93d8671d4e4afee9b148f9998d20e7c upstream.
One of the changes in Sphinx 5.0.0 [1] says [sic]:
5.0.0 final
- #10474: language does not accept None as it value. The default value of language becomes to 'en' now.
[1]: https://www.sphinx-doc.org/en/master/changes.html#release-5-0-0-released-may-30-2022
It results in a new warning from Sphinx 5.0.0 [sic]:
WARNING: Invalid configuration value found: 'language = None'. Update your configuration to a valid langauge code. Falling back to 'en' (English).
Silence the warning by using 'en'.
It works with all the Sphinx versions required for building kernel documentation (1.7.9 or later).
--- Documentation/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/conf.py +1 -1
@@ -161,7 +161,7 @@ finally: # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used:
Greg Kroah-Hartman
maintainerPATCH 856/879 dt-bindings: gpio: altera: correct interrupt-cells
In reply to Greg Kroah-HartmanFrom: Dinh Nguyen <[email protected]>
commit 3a21c3ac93aff7b4522b152399df8f6a041df56d upstream.
update documentation to correctly state the interrupt-cells to be 2.
--- Documentation/devicetree/bindings/gpio/gpio-altera.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/gpio/gpio-altera.txt +3 -2
@@ -9,8 +9,9 @@ Required properties: - The second cell is reserved and is currently unused. - gpio-controller : Marks the device node as a GPIO controller. - interrupt-controller: Mark the device node as an interrupt controller -- #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware. +- #interrupt-cells : Should be 2. The interrupt type is fixed in the hardware. - The first cell is the GPIO offset number within the GPIO controller. + - The second cell is the interrupt trigger type and level flags. - interrupts: Specify the interrupt. - altr,interrupt-type: Specifies the interrupt trigger type the GPIO hardware is synthesized. This field is required if the Altera GPIO controller
@@ -38,6 +39,6 @@ gpio_altr: gpio@ff200000 { altr,interrupt-type = <IRQ_TYPE_EDGE_RISING>; #gpio-cells = <2>; gpio-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; interrupt-controller; };
Greg Kroah-Hartman
maintainerPATCH 857/879 vdpasim: allow to enable a vq repeatedly
In reply to Greg Kroah-HartmanFrom: Eugenio Pérez <[email protected]>
commit 242436973831aa97e8ce19533c6c912ea8def31b upstream.
Code must be resilient to enable a queue many times.
At the moment the queue is resetting so it's definitely not the expected behavior.
v2: set vq->ready = 0 at disable.
Message-Id: <[email protected]>
--- drivers/vdpa/vdpa_sim/vdpa_sim.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/vdpa/vdpa_sim/vdpa_sim.c +4 -1
@@ -353,11 +353,14 @@ static void vdpasim_set_vq_ready(struct {struct vdpasim *vdpasim =vdpa_to_sim (vdpa);struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx]; +bool old_ready;spin_lock (&vdpasim->lock); + old_ready = vq->ready; vq->ready = ready; -if (vq->ready) +if (vq->ready && !old_ready) {vdpasim_queue_ready (vdpasim, idx); + }spin_unlock (&vdpasim->lock); }
Greg Kroah-Hartman
maintainerPATCH 858/879 blk-iolatency: Fix inflight count imbalances and IO hangs on offline
In reply to Greg Kroah-HartmanFrom: Tejun Heo <[email protected]>
commit 8a177a36da6c54c98b8685d4f914cb3637d53c0d upstream.
iolatency needs to track the number of inflight IOs per cgroup. As this tracking can be expensive, it is disabled when no cgroup has iolatency configured for the device. To ensure that the inflight counters stay balanced, iolatency_set_limit() freezes the request_queue while manipulating the enabled counter, which ensures that no IO is in flight and thus all counters are zero.
Unfortunately, iolatency_set_limit() isn't the only place where the enabled counter is manipulated. iolatency_pd_offline() can also dec the counter and trigger disabling. As this disabling happens without freezing the q, this can easily happen while some IOs are in flight and thus leak the counts.
This can be easily demonstrated by turning on iolatency on an one empty cgroup while IOs are in flight in other cgroups and then removing the cgroup. Note that iolatency shouldn't have been enabled elsewhere in the system to ensure that removing the cgroup disables iolatency for the whole device.
The following keeps flipping on and off iolatency on sda:
echo +io > /sys/fs/cgroup/cgroup.subtree_control while true; do
mkdir -p /sys/fs/cgroup/test
echo '8:0 target=100000' > /sys/fs/cgroup/test/io.latency sleep 1
rmdir /sys/fs/cgroup/test
sleep 1
done
and there's concurrent fio generating direct rand reads:
fio --name test --filename=/dev/sda --direct=1 --rw=randread \
--runtime=600 --time_based --iodepth=256 --numjobs=4 --bs=4kwhile monitoring with the following drgn script:
while True:
for css in css_for_each_descendant_pre(prog['blkcg_root'].css.address_of_()):
for pos in hlist_for_each(container_of(css, 'struct blkcg', 'css').blkg_list):
blkg = container_of(pos, 'struct blkcg_gq', 'blkcg_node')
pd = blkg.pd[prog['blkcg_policy_iolatency'].plid]
if pd.value_() == 0:
continue
iolat = container_of(pd, 'struct iolatency_grp', 'pd') inflight = iolat.rq_wait.inflight.counter.value_()
if inflight:
print(f'inflight={inflight} {disk_name(blkg.q.disk).decode("utf-8")} '
f'{cgroup_path(css.cgroup).decode("utf-8")}')
time.sleep(1)
The monitoring output looks like the following:
inflight=1 sda /user.slice
inflight=1 sda /user.slice
...
inflight=14 sda /user.slice
inflight=13 sda /user.slice
inflight=17 sda /user.slice
inflight=15 sda /user.slice
inflight=18 sda /user.slice
inflight=17 sda /user.slice
inflight=20 sda /user.slice
inflight=19 sda /user.slice <- fio stopped, inflight stuck at 19 inflight=19 sda /user.slice
inflight=19 sda /user.slice
If a cgroup with stuck inflight ends up getting throttled, the throttled IOs will never get issued as there's no completion event to wake it up leading to an indefinite hang.
This patch fixes the bug by unifying enable handling into a work item which is automatically kicked off from iolatency_set_min_lat_nsec() which is called from both iolatency_set_limit() and iolatency_pd_offline() paths. Punting to a work item is necessary as iolatency_pd_offline() is called under spinlocks while freezing a request_queue requires a sleepable context.
This also simplifies the code reducing LOC sans the comments and avoids the unnecessary freezes which were happening whenever a cgroup's latency target is newly set or cleared.
--- block/blk-iolatency.c | 122 ++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 58 deletions(-)
block/blk-iolatency.c +64 -58
@@ -87,7 +87,17 @@ struct iolatency_grp;struct blk_iolatency {struct rq_qos rqos;struct timer_list timer; -atomic_t enabled; + +/* +* ->enabled is the master enable switch gating the throttling logic and +* inflight tracking. The number of cgroups which have iolat enabled is +* tracked in ->enable_cnt, and ->enable is flipped on/off accordingly +* from ->enable_work with the request_queue frozen. For details, See +* blkiolatency_enable_work_fn(). +*/ +bool enabled; +atomic_t enable_cnt; +struct work_struct enable_work; };static inline struct blk_iolatency *BLKIOLATENCY (struct rq_qos *rqos)
@@ -95,11 +105,6 @@ static inline struct blk_iolatency *BLKI return container_of(rqos, struct blk_iolatency, rqos); } -static inline bool blk_iolatency_enabled (struct blk_iolatency *blkiolat) -{ -return atomic_read (&blkiolat->enabled) >0 ; -} -struct child_latency_info {spinlock_t lock;
@@ -464,7 +469,7 @@ static void blkcg_iolatency_throttle(strstruct blkcg_gq *blkg = bio->bi_blkg;bool issue_as_root =bio_issue_as_root_blkg (bio); -if (!blk_iolatency_enabled (blkiolat)) +if (!blkiolat->enabled)return ;while (blkg && blkg->parent) {
@@ -594,7 +599,6 @@ static void blkcg_iolatency_done_bio(stru64 window_start;u64 now;bool issue_as_root =bio_issue_as_root_blkg (bio); -bool enabled = false;int inflight =0 ; blkg = bio->bi_blkg;
@@ -605,8 +609,7 @@ static void blkcg_iolatency_done_bio(strif (!iolat)return ; - enabled =blk_iolatency_enabled (iolat->blkiolat); -if (!enabled) +if (!iolat->blkiolat->enabled)return ; now =ktime_to_ns (ktime_get ());
@@ -645,6 +648,7 @@ static void blkcg_iolatency_exit(structstruct blk_iolatency *blkiolat =BLKIOLATENCY (rqos);del_timer_sync (&blkiolat->timer); +flush_work (&blkiolat->enable_work);blkcg_deactivate_policy (rqos->q, &blkcg_policy_iolatency);kfree (blkiolat); }
@@ -716,6 +720,44 @@ next:rcu_read_unlock (); } +/** +* blkiolatency_enable_work_fn - Enable or disable iolatency on the device +* @work: enable_work of the blk_iolatency of interest +* +* iolatency needs to keep track of the number of in-flight IOs per cgroup. This +* is relatively expensive as it involves walking up the hierarchy twice for +* every IO. Thus, if iolatency is not enabled in any cgroup for the device, we +* want to disable the in-flight tracking. +* +* We have to make sure that the counting is balanced - we don't want to leak +* the in-flight counts by disabling accounting in the completion path while IOs +* are in flight. This is achieved by ensuring that no IO is in flight by +* freezing the queue while flipping ->enabled. As this requires a sleepable +* context, ->enabled flipping is punted to this work function. +*/ +static void blkiolatency_enable_work_fn (struct work_struct *work) +{ + struct blk_iolatency *blkiolat = container_of(work, struct blk_iolatency, + enable_work); +bool enabled; + +/* +* There can only be one instance of this function running for @blkiolat +* and it's guaranteed to be executed at least once after the latest +* ->enabled_cnt modification. Acting on the latest ->enable_cnt is +* sufficient. +* +* Also, we know @blkiolat is safe to access as ->enable_work is flushed +* in blkcg_iolatency_exit(). +*/ + enabled =atomic_read (&blkiolat->enable_cnt); +if (enabled != blkiolat->enabled) { +blk_mq_freeze_queue (blkiolat->rqos.q); + blkiolat->enabled = enabled; +blk_mq_unfreeze_queue (blkiolat->rqos.q); + } +} +int blk_iolatency_init (struct request_queue *q) {struct blk_iolatency *blkiolat;
@@ -741,17 +783,15 @@ int blk_iolatency_init(struct request_qu }timer_setup (&blkiolat->timer, blkiolatency_timer_fn,0 ); +INIT_WORK (&blkiolat->enable_work, blkiolatency_enable_work_fn);return 0 ; } -/* -* return 1 for enabling iolatency, return -1 for disabling iolatency, otherwise -* return 0. -*/ -static int iolatency_set_min_lat_nsec (struct blkcg_gq *blkg,u64 val) +static void iolatency_set_min_lat_nsec (struct blkcg_gq *blkg,u64 val) {struct iolatency_grp *iolat =blkg_to_lat (blkg); +struct blk_iolatency *blkiolat = iolat->blkiolat;u64 oldval = iolat->min_lat_nsec; iolat->min_lat_nsec = val;
@@ -759,13 +799,15 @@ static int iolatency_set_min_lat_nsec(st iolat->cur_win_nsec =min_t (u64, iolat->cur_win_nsec,BLKIOLATENCY_MAX_WIN_SIZE ); -if (!oldval && val) -return 1 ; +if (!oldval && val) { +if (atomic_inc_return (&blkiolat->enable_cnt) ==1 ) +schedule_work (&blkiolat->enable_work); + }if (oldval && !val) {blkcg_clear_delay (blkg); -return -1 ; +if (atomic_dec_return (&blkiolat->enable_cnt) ==0 ) +schedule_work (&blkiolat->enable_work); } -return 0 ; }static void iolatency_clear_scaling (struct blkcg_gq *blkg)
@@ -797,7 +839,6 @@ static ssize_t iolatency_set_limit(strucu64 lat_val =0 ;u64 oldval;int ret; -int enable =0 ; ret =blkg_conf_prep (blkcg, &blkcg_policy_iolatency, buf, &ctx);if (ret)
@@ -832,41 +873,12 @@ static ssize_t iolatency_set_limit(struc blkg = ctx.blkg; oldval = iolat->min_lat_nsec; - enable =iolatency_set_min_lat_nsec (blkg, lat_val); -if (enable) { -if (!blk_get_queue (blkg->q)) { - ret = -ENODEV ; - goto out; - } - -blkg_get (blkg); - } - -if (oldval != iolat->min_lat_nsec) { +iolatency_set_min_lat_nsec (blkg, lat_val); +if (oldval != iolat->min_lat_nsec)iolatency_clear_scaling (blkg); - } - ret =0 ; out:blkg_conf_finish (&ctx); -if (ret ==0 && enable) { -struct iolatency_grp *tmp =blkg_to_lat (blkg); -struct blk_iolatency *blkiolat = tmp->blkiolat; - -blk_mq_freeze_queue (blkg->q); - -if (enable ==1 ) -atomic_inc (&blkiolat->enabled); -else if (enable ==-1 ) -atomic_dec (&blkiolat->enabled); -else -WARN_ON_ONCE (1 ); - -blk_mq_unfreeze_queue (blkg->q); - -blkg_put (blkg); -blk_put_queue (blkg->q); - }return ret ?: nbytes; }
@@ -1005,14 +1017,8 @@ static void iolatency_pd_offline(struct {struct iolatency_grp *iolat =pd_to_lat (pd);struct blkcg_gq *blkg =lat_to_blkg (iolat); -struct blk_iolatency *blkiolat = iolat->blkiolat; -int ret; - ret =iolatency_set_min_lat_nsec (blkg,0 ); -if (ret ==1 ) -atomic_inc (&blkiolat->enabled); -if (ret ==-1 ) -atomic_dec (&blkiolat->enabled); +iolatency_set_min_lat_nsec (blkg,0 );iolatency_clear_scaling (blkg); }
Greg Kroah-Hartman
maintainerPATCH 859/879 coresight: core: Fix coresight device probe failure issue
In reply to Greg Kroah-HartmanFrom: Mao Jinlong <[email protected]>
commit 8c1d3f79d9ca48e406b78e90e94cf09a8c076bf2 upstream.
It is possibe that probe failure issue happens when the device and its child_device's probe happens at the same time. In coresight_make_links, has_conns_grp is true for parent, but has_conns_grp is false for child device as has_conns_grp is set to true in coresight_create_conns_sysfs_group. The probe of parent device will fail at this condition. Add has_conns_grp check for child device before make the links and make the process from device_register to connection_create be atomic to avoid this probe failure issue.
--- drivers/hwtracing/coresight/coresight-core.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-)
drivers/hwtracing/coresight/coresight-core.c +22 -11
@@ -1379,7 +1379,7 @@ static int coresight_fixup_device_conns(continue ; conn->child_dev =coresight_find_csdev_by_fwnode (conn->child_fwnode); -if (conn->child_dev) { +if (conn->child_dev && conn->child_dev->has_conns_grp) { ret =coresight_make_links (csdev, conn, conn->child_dev);if (ret)
@@ -1571,6 +1571,7 @@ struct coresight_device *coresight_regisint nr_refcnts =1 ;atomic_t *refcnts =NULL ;struct coresight_device *csdev; +bool registered = false; csdev =kzalloc (sizeof (*csdev),GFP_KERNEL );if (!csdev) {
@@ -1591,7 +1592,8 @@ struct coresight_device *coresight_regis refcnts =kcalloc (nr_refcnts,sizeof (*refcnts),GFP_KERNEL );if (!refcnts) { ret = -ENOMEM ; - goto err_free_csdev; +kfree (csdev); + goto err_out; } csdev->refcnt = refcnts;
@@ -1616,6 +1618,13 @@ struct coresight_device *coresight_regis csdev->dev.fwnode =fwnode_handle_get (dev_fwnode (desc->dev));dev_set_name (&csdev->dev,"%s" , desc->name); +/* +* Make sure the device registration and the connection fixup +* are synchronised, so that we don't see uninitialised devices +* on the coresight bus while trying to resolve the connections. +*/ +mutex_lock (&coresight_mutex); + ret =device_register (&csdev->dev);if (ret) {put_device (&csdev->dev);
@@ -1623,7 +1632,7 @@ struct coresight_device *coresight_regis* All resources are free'd explicitly via * coresight_device_release(), triggered from put_device(). */ - goto err_out; + goto out_unlock; } if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
@@ -1638,11 +1647,11 @@ struct coresight_device *coresight_regis* from put_device(), which is in turn called from * function device_unregister(). */ - goto err_out; + goto out_unlock; } } - -mutex_lock (&coresight_mutex); +/* Device is now registered */ + registered = true; ret =coresight_create_conns_sysfs_group (csdev);if (!ret)
@@ -1652,16 +1661,18 @@ struct coresight_device *coresight_regisif (!ret && cti_assoc_ops && cti_assoc_ops->add) cti_assoc_ops->add (csdev); +out_unlock:mutex_unlock (&coresight_mutex); -if (ret) { +/* Success */ +if (!ret) +return csdev; + +/* Unregister the device if needed */ +if (registered) {coresight_unregister (csdev);return ERR_PTR (ret); } -return csdev; - -err_free_csdev: -kfree (csdev); err_out:/* Cleanup the connection information */ coresight_release_platform_data (NULL , desc->pdata);
Greg Kroah-Hartman
maintainerPATCH 860/879 phy: qcom-qmp: fix reset-controller leak on probe errors
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 4d2900f20edfe541f75756a00deeb2ffe7c66bc1 upstream.
Make sure to release the lane reset controller in case of a late probe error (e.g. probe deferral).
Note that due to the reset controller being defined in devicetree in "lane" child nodes, devm_reset_control_get_exclusive() cannot be used directly.
--- drivers/phy/qualcomm/phy-qcom-qmp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/phy/qualcomm/phy-qcom-qmp.c +9 -0
@@ -5818,6 +5818,11 @@ static const struct phy_ops qcom_qmp_pci .owner = THIS_MODULE, }; +static void qcom_qmp_reset_control_put (void *data) +{ +reset_control_put (data); +} +static int qcom_qmp_phy_create (struct device *dev,struct device_node *np,int id,void __iomem *serdes,const struct qmp_phy_cfg *cfg)
@@ -5912,6 +5917,10 @@ int qcom_qmp_phy_create(struct device *ddev_err (dev,"failed to get lane%d reset\n" , id);return PTR_ERR (qphy->lane_rst); } + ret =devm_add_action_or_reset (dev, qcom_qmp_reset_control_put, + qphy->lane_rst); +if (ret) +return ret; }if (cfg->type ==PHY_TYPE_UFS || cfg->type ==PHY_TYPE_PCIE )
Greg Kroah-Hartman
maintainerPATCH 861/879 net: ipa: fix page free in ipa_endpoint_trans_release()
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
commit 155c0c90bca918de6e4327275dfc1d97fd604115 upstream.
Currently the (possibly compound) page used for receive buffers are freed using __free_pages(). But according to this comment above the definition of that function, that's wrong:
If you want to use the page's reference count to decide when to free the allocation, you should allocate a compound page, and use put_page() instead of __free_pages().
Convert the call to __free_pages() in ipa_endpoint_trans_release() to use put_page() instead.
--- drivers/net/ipa/ipa_endpoint.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/net/ipa/ipa_endpoint.c +2 -5
@@ -1385,11 +1385,8 @@ void ipa_endpoint_trans_release(struct i }else {struct page *page = trans->data; -if (page) { -u32 buffer_size = endpoint->data->rx.buffer_size; - -__free_pages (page,get_order (buffer_size)); - } +if (page) +put_page (page); } }
Greg Kroah-Hartman
maintainerPATCH 862/879 net: ipa: fix page free in ipa_endpoint_replenish_one()
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
commit 70132763d5d2e94cd185e3aa92ac6a3ba89068fa upstream.
Currently the (possibly compound) pages used for receive buffers are freed using __free_pages(). But according to this comment above the definition of that function, that's wrong:
If you want to use the page's reference count to decide when to free the allocation, you should allocate a compound page, and use put_page() instead of __free_pages().
Convert the call to __free_pages() in ipa_endpoint_replenish_one() to use put_page() instead.
--- drivers/net/ipa/ipa_endpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ipa/ipa_endpoint.c +1 -1
@@ -1062,7 +1062,7 @@ static int ipa_endpoint_replenish_one(st ret =gsi_trans_page_add (trans, page, len, offset);if (ret) -__free_pages (page,get_order (buffer_size)); +put_page (page);else trans->data = page;/* transaction owns page now */
Greg Kroah-Hartman
maintainerPATCH 863/879 media: lirc: add missing exceptions for lirc uapi header file
In reply to Greg Kroah-HartmanFrom: Sean Young <[email protected]>
commit b1c8312c6bd70e2c41f96183936fdb6f4f07cc0e upstream.
Commit e5499dd7253c ("media: lirc: revert removal of unused feature flags") reintroduced unused feature flags in the lirc uapi header, but failed to reintroduce the necessary exceptions for the docs.
--- Documentation/userspace-api/media/lirc.h.rst.exceptions | 2 ++ 1 file changed, 2 insertions(+)
Documentation/userspace-api/media/lirc.h.rst.exceptions +2 -0
@@ -30,6 +30,8 @@ ignore define LIRC_CAN_REC ignore define LIRC_CAN_SEND_MASK ignore define LIRC_CAN_REC_MASK +ignore define LIRC_CAN_SET_REC_FILTER +ignore define LIRC_CAN_NOTIFY_DECODE # Obsolete ioctls
Signature · 1 line
2.36.1
Greg Kroah-Hartman
maintainerPATCH 864/879 kseltest/cgroup: Make test_stress.sh work if run interactively
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
commit 213adc63dfbcdff9a0c19ec1f2681fda9c05cf6d upstream.
Commit 54de76c01239 ("kselftest/cgroup: fix test_stress.sh to use OUTPUT dir") changes the test_core command path from . to $OUTPUT. However, variable OUTPUT may not be defined if the command is run interactively. Fix that by using ${OUTPUT:-.} to cover both cases.
--- tools/testing/selftests/cgroup/test_stress.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/cgroup/test_stress.sh +1 -1
@@ -1,4 +1,4 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 -./with_stress.sh -s subsys -s fork ${OUTPUT}/test_core +./with_stress.sh -s subsys -s fork ${OUTPUT:-.}/test_core
Greg Kroah-Hartman
maintainerPATCH 865/879 perf evlist: Extend arch_evsel__must_be_in_group to support hybrid systems
In reply to Greg Kroah-HartmanFrom: Zhengjun Xing <[email protected]>
commit e69a5c010246ca6a87c4e6f13d0a291954bdece8 upstream.
For the hybrid system, the "slots" event changes to "cpu_core/slots/", need extend API arch_evsel__must_be_in_group() to support hybrid systems.
In the origin code, for hybrid system event "cpu_core/slots/", the output of the API arch_evsel__must_be_in_group() is "false" (in fact,it should be "true"). Currently only one API evsel__remove_from_group() calls it. In evsel__remove_from_group(), it adds the second condition to check, so the output of evsel__remove_from_group() still is correct. That's the reason why there isn't an instant error. I'd like to fix the issue found in API arch_evsel__must_be_in_group() in case someone else using the function in the other place.
--- tools/perf/arch/x86/util/evsel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/arch/x86/util/evsel.c +1 -1
@@ -38,6 +38,6 @@ bool arch_evsel__must_be_in_group(constreturn false;return evsel->name && - (!strcasecmp (evsel->name,"slots" ) || + (strcasestr (evsel->name,"slots" ) ||strcasestr (evsel->name,"topdown" )); }
Greg Kroah-Hartman
maintainerPATCH 866/879 Revert "random: use static branch for crng_ready()"
In reply to Greg Kroah-HartmanFrom: "Jason A. Donenfeld" <[email protected]>
This reverts upstream commit f5bda35fba615ace70a656d4700423fa6c9bebee from stable. It's not essential and will take some time during 5.19 to work out properly.
--- drivers/char/random.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
drivers/char/random.c +2 -10
@@ -78,8 +78,7 @@ static enum {CRNG_EARLY =1 ,/* At least POOL_EARLY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ } crng_init__read_mostly =CRNG_EMPTY ; -static DEFINE_STATIC_KEY_FALSE (crng_is_ready); -#define crng_ready () (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) +#define crng_ready () (likely(crng_init >= CRNG_READY))/* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD (crng_init_wait);static struct fasync_struct *fasync;
@@ -109,11 +108,6 @@ bool rng_is_initialized(void) }EXPORT_SYMBOL (rng_is_initialized); -static void __cold crng_set_ready (struct work_struct *work) -{ -static_branch_enable (&crng_is_ready); -} -/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */ static void try_to_generate_entropy (void );
@@ -267,7 +261,7 @@ static void crng_reseed(void) ++next_gen;WRITE_ONCE (base_crng.generation, next_gen);WRITE_ONCE (base_crng.birth, jiffies); -if (!static_branch_likely (&crng_is_ready)) +if (!crng_ready ()) crng_init =CRNG_READY ;spin_unlock_irqrestore (&base_crng.lock, flags);memzero_explicit (key,sizeof (key));
@@ -710,7 +704,6 @@ static void extract_entropy(void *buf, sstatic void __cold _credit_init_bits (size_t bits) { -static struct execute_work set_ready;unsigned int new, orig, add;unsigned long flags;
@@ -726,7 +719,6 @@ static void __cold _credit_init_bits(sizif (orig <POOL_READY_BITS && new >=POOL_READY_BITS ) {crng_reseed ();/* Sets crng_init to CRNG_READY under base_crng.lock. */ -execute_in_process_context (crng_set_ready, &set_ready);process_random_ready_list ();wake_up_interruptible (&crng_init_wait);kill_fasync (&fasync,SIGIO ,POLL_IN );
Greg Kroah-Hartman
maintainerPATCH 867/879 staging: r8188eu: delete rtw_wx_read/write32()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 4d0cc9e0e53e9946d7b8dc58279c62dfa7a2191b upstream.
These debugging tools let you call:
status = usb_control_msg_recv/send(udev, 0, REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ/WRITE, value, REALTEK_USB_VENQT_CMD_IDX, io_buf, size, RTW_USB_CONTROL_MSG_TIMEOUT, GFP_KERNEL);
with a user controlled "value" in the 0-0xffff range. It's not a valid API.
--- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 86 --------------------------- 1 file changed, 2 insertions(+), 84 deletions(-)
drivers/staging/r8188eu/os_dep/ioctl_linux.c +2 -84
@@ -1888,88 +1888,6 @@ static int rtw_wx_get_nick(struct net_dereturn 0 ; } -static int rtw_wx_read32 (struct net_device *dev, -struct iw_request_info *info, -union iwreq_data *wrqu,char *extra) -{ -struct adapter *padapter; -struct iw_point *p; -u16 len; -u32 addr; -u32 data32; -u32 bytes; -u8 *ptmp; -int ret; - - padapter = (struct adapter *)rtw_netdev_priv (dev); - p = &wrqu->data; - len = p->length; - ptmp =memdup_user (p->pointer, len); -if (IS_ERR (ptmp)) -return PTR_ERR (ptmp); - - bytes =0 ; - addr =0 ; -sscanf (ptmp,"%d,%x" , &bytes, &addr); - -switch (bytes) { -case 1 : - data32 =rtw_read8 (padapter, addr); -sprintf (extra,"0x%02X" , data32); -break ; -case 2 : - data32 =rtw_read16 (padapter, addr); -sprintf (extra,"0x%04X" , data32); -break ; -case 4 : - data32 =rtw_read32 (padapter, addr); -sprintf (extra,"0x%08X" , data32); -break ; -default : - ret = -EINVAL ; - goto err_free_ptmp; - } - -kfree (ptmp); -return 0 ; - -err_free_ptmp: -kfree (ptmp); -return ret; -} - -static int rtw_wx_write32 (struct net_device *dev, -struct iw_request_info *info, -union iwreq_data *wrqu,char *extra) -{ -struct adapter *padapter = (struct adapter *)rtw_netdev_priv (dev); - -u32 addr; -u32 data32; -u32 bytes; - - bytes =0 ; - addr =0 ; - data32 =0 ; -sscanf (extra,"%d,%x,%x" , &bytes, &addr, &data32); - -switch (bytes) { -case 1 : -rtw_write8 (padapter, addr, (u8 )data32); -break ; -case 2 : -rtw_write16 (padapter, addr, (u16 )data32); -break ; -case 4 : -rtw_write32 (padapter, addr, data32); -break ; -default : -return -EINVAL ; - } - -return 0 ; -} -static int rtw_wx_read_rf (struct net_device *dev,struct iw_request_info *info,union iwreq_data *wrqu,char *extra)
@@ -3897,8 +3815,8 @@ static const struct iw_priv_args rtw_pri };static iw_handler rtw_private_handler[] = { -rtw_wx_write32,/* 0x00 */ -rtw_wx_read32,/* 0x01 */ +NULL ,/* 0x00 */ +NULL ,/* 0x01 */ NULL ,/* 0x02 */ NULL ,/* 0x03 */ /* for MM DTV platform */
Greg Kroah-Hartman
maintainerPATCH 868/879 binder: fix sender_euid type in uapi header
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
commit 8cc5b032240ae5220b62c689c20459d3e1825b2d upstream.
The {pid,uid}_t fields of struct binder_transaction were recently replaced to use kernel types in commit 169adc2b6b3c ("android/binder.h:
add linux/android/binder(fs).h to UAPI compile-test coverage").
However, using __kernel_uid_t here breaks backwards compatibility in architectures using 16-bits for this type, since glibc and some others still expect a 32-bit uid_t. Instead, let's use __kernel_uid32_t which avoids this compatibility problem.
--- include/uapi/linux/android/binder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/uapi/linux/android/binder.h +1 -1
@@ -289,7 +289,7 @@ struct binder_transaction_data {/* General information about the transaction. */ __u32 flags;__kernel_pid_t sender_pid; -__kernel_uid_t sender_euid; +__kernel_uid32_t sender_euid;binder_size_t data_size;/* number of bytes of data */ binder_size_t offsets_size;/* number of bytes of offsets */
Greg Kroah-Hartman
maintainerPATCH 869/879 RDMA/hns: Remove the num_cqc_timer variable
In reply to Greg Kroah-HartmanFrom: Yixing Liu <[email protected]>
commit db5dfbf5b201df65c1f5332c4d9d5e7c2f42396b upstream.
The bt number of cqc_timer of HIP09 increases compared with that of HIP08. Therefore, cqc_timer_bt_num and num_cqc_timer do not match. As a result, the driver may fail to allocate cqc_timer. So the driver needs to uniquely uses cqc_timer_bt_num to represent the bt number of cqc_timer.
--- drivers/infiniband/hw/hns/hns_roce_device.h | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +-- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- drivers/infiniband/hw/hns/hns_roce_main.c | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-)
drivers/infiniband/hw/hns/hns_roce_device.h +0 -1
@@ -731,7 +731,6 @@ struct hns_roce_caps {u32 num_pi_qps;u32 reserved_qps;int num_qpc_timer; -int num_cqc_timer;u32 num_srqs;u32 max_wqes;u32 max_srq_wrs;
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +1 -2
@@ -1965,7 +1965,7 @@ static void set_default_caps(struct hns_ caps->num_mtpts =HNS_ROCE_V2_MAX_MTPT_NUM ; caps->num_pds =HNS_ROCE_V2_MAX_PD_NUM ; caps->num_qpc_timer =HNS_ROCE_V2_MAX_QPC_TIMER_NUM ; - caps->num_cqc_timer =HNS_ROCE_V2_MAX_CQC_TIMER_NUM ; + caps->cqc_timer_bt_num =HNS_ROCE_V2_MAX_CQC_TIMER_BT_NUM ; caps->max_qp_init_rdma =HNS_ROCE_V2_MAX_QP_INIT_RDMA ; caps->max_qp_dest_rdma =HNS_ROCE_V2_MAX_QP_DEST_RDMA ;
@@ -2261,7 +2261,6 @@ static int hns_roce_query_pf_caps(struct caps->max_rq_sg =roundup_pow_of_two (caps->max_rq_sg); caps->max_extend_sg =le32_to_cpu (resp_a->max_extend_sg); caps->num_qpc_timer =le16_to_cpu (resp_a->num_qpc_timer); - caps->num_cqc_timer =le16_to_cpu (resp_a->num_cqc_timer); caps->max_srq_sges =le16_to_cpu (resp_a->max_srq_sges); caps->max_srq_sges =roundup_pow_of_two (caps->max_srq_sges); caps->num_aeq_vectors = resp_a->num_aeq_vectors;
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +1 -1
@@ -41,7 +41,7 @@#define HNS_ROCE_V2_MAX_SRQ_WR 0x8000#define HNS_ROCE_V2_MAX_SRQ_SGE 64#define HNS_ROCE_V2_MAX_CQ_NUM 0x100000 -#define HNS_ROCE_V2_MAX_CQC_TIMER_NUM 0x100 +#define HNS_ROCE_V2_MAX_CQC_TIMER_BT_NUM 0x100#define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000#define HNS_ROCE_V2_MAX_CQE_NUM 0x400000#define HNS_ROCE_V2_MAX_RQ_SGE_NUM 64
drivers/infiniband/hw/hns/hns_roce_main.c +1 -1
@@ -737,7 +737,7 @@ static int hns_roce_init_hem(struct hns_ ret =hns_roce_init_hem_table (hr_dev, &hr_dev->cqc_timer_table,HEM_TYPE_CQC_TIMER , hr_dev->caps.cqc_timer_entry_sz, - hr_dev->caps.num_cqc_timer,1 ); + hr_dev->caps.cqc_timer_bt_num,1 );if (ret) {dev_err (dev,"Failed to init CQC timer memory, aborting.\n" );
Greg Kroah-Hartman
maintainerPATCH 870/879 RDMA/rxe: Generate a completion for unsupported/invalid opcode
In reply to Greg Kroah-HartmanFrom: Xiao Yang <[email protected]>
commit 2f917af777011c88e977b9b9a5d00b280d3a59ce upstream.
Current rxe_requester() doesn't generate a completion when processing an unsupported/invalid opcode. If rxe driver doesn't support a new opcode (e.g. RDMA Atomic Write) and RDMA library supports it, an application using the new opcode can reproduce this issue. Fix the issue by calling "goto err;".
--- drivers/infiniband/sw/rxe/rxe_req.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/sw/rxe/rxe_req.c +1 -1
@@ -661,7 +661,7 @@ next_wqe: opcode =next_opcode (qp, wqe, wqe->wr.opcode);if (unlikely (opcode <0 )) { wqe->status =IB_WC_LOC_QP_OP_ERR ; - goto exit; + goto err; } mask = rxe_opcode[opcode].mask;
Greg Kroah-Hartman
maintainerPATCH 871/879 ext4: only allow test_dummy_encryption when supported
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 5f41fdaea63ddf96d921ab36b2af4a90ccdb5744 upstream.
Make the test_dummy_encryption mount option require that the encrypt feature flag be already enabled on the filesystem, rather than automatically enabling it. Practically, this means that "-O encrypt" will need to be included in MKFS_OPTIONS when running xfstests with the test_dummy_encryption mount option. (ext4/053 also needs an update.)
Moreover, as long as the preconditions for test_dummy_encryption are being tightened anyway, take the opportunity to start rejecting it when !CONFIG_FS_ENCRYPTION rather than ignoring it.
The motivation for requiring the encrypt feature flag is that:
- Having the filesystem auto-enable feature flags is problematic, as it bypasses the usual sanity checks. The specific issue which came up recently is that in kernel versions where ext4 supports casefold but not encrypt+casefold (v5.1 through v5.10), the kernel will happily add the encrypt flag to a filesystem that has the casefold flag, making it unmountable -- but only for subsequent mounts, not the initial one. This confused the casefold support detection in xfstests, causing generic/556 to fail rather than be skipped.
- The xfstests-bld test runners (kvm-xfstests et al.) already use the required mkfs flag, so they will not be affected by this change. Only users of test_dummy_encryption alone will be affected. But, this option has always been for testing only, so it should be fine to require that the few users of this option update their test scripts.
- f2fs already requires it (for its equivalent feature flag).
--- fs/ext4/ext4.h | 6 ----- fs/ext4/super.c | 60 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 28 deletions(-)
fs/ext4/ext4.h +0 -6
@@ -1440,12 +1440,6 @@ struct ext4_super_block {#ifdef __KERNEL__ -#ifdef CONFIG_FS_ENCRYPTION -#define DUMMY_ENCRYPTION_ENABLED (sbi) ((sbi)->s_dummy_enc_policy.policy != NULL) -#else -#define DUMMY_ENCRYPTION_ENABLED (sbi) (0) -#endif -/* Number of quota types we support */ #define EXT4_MAXQUOTAS 3
fs/ext4/super.c +38 -22
93 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 872/879 fs: add two trivial lookup helpers
In reply to Greg Kroah-HartmanFrom: Christian Brauner <[email protected]>
commit 00675017e0aeba5305665c52ded4ddce6a4c0231 upstream.
Similar to the addition of lookup_one() add a version of lookup_one_unlocked() and lookup_one_positive_unlocked() that take idmapped mounts into account. This is required to port overlay to support idmapped base layers.
--- fs/namei.c | 70 ++++++++++++++++++++++++++++++++++++++++++-------- include/linux/namei.h | 6 ++++ 2 files changed, 66 insertions(+), 10 deletions(-)
fs/namei.c +60 -10
@@ -2768,7 +2768,8 @@ struct dentry *lookup_one(struct user_naEXPORT_SYMBOL (lookup_one);/** -* lookup_one_len_unlocked - filesystem helper to lookup single pathname component +* lookup_one_unlocked - filesystem helper to lookup single pathname component +* @mnt_userns: idmapping of the mount the lookup is performed from * @name: pathname component to lookup * @base: base directory to lookup from * @len: maximum length @len should be interpreted to
@@ -2779,14 +2780,15 @@ EXPORT_SYMBOL(lookup_one);* Unlike lookup_one_len, it should be called without the parent * i_mutex held, and will take the i_mutex itself if necessary. */ -struct dentry *lookup_one_len_unlocked (const char *name, -struct dentry *base,int len) +struct dentry *lookup_one_unlocked (struct user_namespace *mnt_userns, +const char *name,struct dentry *base, +int len) {struct qstr this;int err;struct dentry *ret; - err =lookup_one_common (&init_user_ns, name, base, len, &this); + err =lookup_one_common (mnt_userns, name, base, len, &this);if (err)return ERR_PTR (err);
@@ -2795,6 +2797,59 @@ struct dentry *lookup_one_len_unlocked(c ret =lookup_slow (&this, base,0 );return ret; } +EXPORT_SYMBOL (lookup_one_unlocked); + +/** +* lookup_one_positive_unlocked - filesystem helper to lookup single +* pathname component +* @mnt_userns: idmapping of the mount the lookup is performed from +* @name: pathname component to lookup +* @base: base directory to lookup from +* @len: maximum length @len should be interpreted to +* +* This helper will yield ERR_PTR(-ENOENT) on negatives. The helper returns +* known positive or ERR_PTR(). This is what most of the users want. +* +* Note that pinned negative with unlocked parent _can_ become positive at any +* time, so callers of lookup_one_unlocked() need to be very careful; pinned +* positives have >d_inode stable, so this one avoids such problems. +* +* Note that this routine is purely a helper for filesystem usage and should +* not be called by generic code. +* +* The helper should be called without i_mutex held. +*/ +struct dentry *lookup_one_positive_unlocked (struct user_namespace *mnt_userns, +const char *name, +struct dentry *base,int len) +{ +struct dentry *ret =lookup_one_unlocked (mnt_userns, name, base, len); + +if (!IS_ERR (ret) &&d_flags_negative (smp_load_acquire (&ret->d_flags))) { +dput (ret); + ret =ERR_PTR (-ENOENT ); + } +return ret; +} +EXPORT_SYMBOL (lookup_one_positive_unlocked); + +/** +* lookup_one_len_unlocked - filesystem helper to lookup single pathname component +* @name: pathname component to lookup +* @base: base directory to lookup from +* @len: maximum length @len should be interpreted to +* +* Note that this routine is purely a helper for filesystem usage and should +* not be called by generic code. +* +* Unlike lookup_one_len, it should be called without the parent +* i_mutex held, and will take the i_mutex itself if necessary. +*/ +struct dentry *lookup_one_len_unlocked (const char *name, +struct dentry *base,int len) +{ +return lookup_one_unlocked (&init_user_ns, name, base, len); +}EXPORT_SYMBOL (lookup_one_len_unlocked);/*
@@ -2808,12 +2863,7 @@ EXPORT_SYMBOL(lookup_one_len_unlocked);struct dentry *lookup_positive_unlocked (const char *name,struct dentry *base,int len) { -struct dentry *ret =lookup_one_len_unlocked (name, base, len); -if (!IS_ERR (ret) &&d_flags_negative (smp_load_acquire (&ret->d_flags))) { -dput (ret); - ret =ERR_PTR (-ENOENT ); - } -return ret; +return lookup_one_positive_unlocked (&init_user_ns, name, base, len); }EXPORT_SYMBOL (lookup_positive_unlocked);
include/linux/namei.h +6 -0
@@ -69,6 +69,12 @@ extern struct dentry *lookup_one_len(conextern struct dentry *lookup_one_len_unlocked (const char *,struct dentry *,int );extern struct dentry *lookup_positive_unlocked (const char *,struct dentry *,int );struct dentry *lookup_one (struct user_namespace *,const char *,struct dentry *,int ); +struct dentry *lookup_one_unlocked (struct user_namespace *mnt_userns, +const char *name,struct dentry *base, +int len); +struct dentry *lookup_one_positive_unlocked (struct user_namespace *mnt_userns, +const char *name, +struct dentry *base,int len);extern int follow_down_one (struct path *);extern int follow_down (struct path *);
Greg Kroah-Hartman
maintainerPATCH 873/879 exportfs: support idmapped mounts
In reply to Greg Kroah-HartmanFrom: Christian Brauner <[email protected]>
commit 3a761d72fa62eec8913e45d29375344f61706541 upstream.
Make the two locations where exportfs helpers check permission to lookup a given inode idmapped mount aware by switching it to the lookup_one() helper. This is a bugfix for the open_by_handle_at() system call which doesn't take idmapped mounts into account currently. It's not tied to a specific commit so we'll just Cc stable.
In addition this is required to support idmapped base layers in overlay. The overlay filesystem uses exportfs to encode and decode file handles for its index=on mount option and when nfs_export=on.
--- fs/exportfs/expfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/exportfs/expfs.c +3 -2
@@ -145,7 +145,7 @@ static struct dentry *reconnect_one(struif (err) goto out_err;dprintk ("%s: found name: %s\n" , __func__, nbuf); - tmp =lookup_one_len_unlocked (nbuf, parent,strlen (nbuf)); + tmp =lookup_one_unlocked (mnt_user_ns (mnt), nbuf, parent,strlen (nbuf));if (IS_ERR (tmp)) {dprintk ("%s: lookup failed: %d\n" , __func__,PTR_ERR (tmp)); err =PTR_ERR (tmp);
@@ -525,7 +525,8 @@ exportfs_decode_fh_raw(struct vfsmount * }inode_lock (target_dir->d_inode); - nresult =lookup_one_len (nbuf, target_dir,strlen (nbuf)); + nresult =lookup_one (mnt_user_ns (mnt), nbuf, + target_dir,strlen (nbuf));if (!IS_ERR (nresult)) {if (unlikely (nresult->d_inode != result->d_inode)) {dput (nresult);
Greg Kroah-Hartman
maintainerPATCH 874/879 fs/ntfs3: Fix invalid free in log_replay
In reply to Greg Kroah-HartmanFrom: Namjae Jeon <[email protected]>
commit f26967b9f7a830e228bb13fb41bd516ddd9d789d upstream.
log_read_rst() returns ENOMEM error when there is not enough memory. In this case, if info is returned without initialization,
it attempts to kfree the uninitialized info->r_page pointer. This patch moves the memset initialization code to before log_read_rst() is called.
--- fs/ntfs3/fslog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ntfs3/fslog.c +3 -3
@@ -1185,8 +1185,6 @@ static int log_read_rst(struct ntfs_logif (!r_page)return -ENOMEM ; -memset (info,0 ,sizeof (struct restart_info )); -/* Determine which restart area we are looking for. */ if (first) { vbo =0 ;
@@ -3791,10 +3789,11 @@ int log_replay(struct ntfs_inode *ni, boif (!log)return -ENOMEM ; +memset (&rst_info,0 ,sizeof (struct restart_info )); + log->ni = ni; log->l_size = l_size; log->one_page_buf =kmalloc (page_size,GFP_NOFS ); -if (!log->one_page_buf) { err = -ENOMEM ; goto out;
@@ -3842,6 +3841,7 @@ int log_replay(struct ntfs_inode *ni, boif (rst_info.vbo) goto check_restart_area; +memset (&rst_info2,0 ,sizeof (struct restart_info )); err =log_read_rst (log, l_size, false, &rst_info2);/* Determine which restart area to use. */
Greg Kroah-Hartman
maintainerPATCH 875/879 md: Dont set mddev private to NULL in raid0 pers->free
In reply to Greg Kroah-HartmanFrom: Xiao Ni <[email protected]>
commit 0f2571ad7a30ff6b33cde142439f9378669f8b4f upstream.
In normal stop process, it does like this:
do_md_stop
|
__md_stop (pers->free(); mddev->private=NULL)
| md_free (free mddev)__md_stop sets mddev->private to NULL after pers->free. The raid device will be stopped and mddev memory is free. But in reshape, it doesn't free the mddev and mddev will still be used in new raid.
In reshape, it first sets mddev->private to new_pers and then runs old_pers->free(). Now raid0 sets mddev->private to NULL in raid0_free. The new raid can't work anymore. It will panic when dereference mddev->private because of NULL pointer dereference.
It can panic like this:
[63010.814972] kernel BUG at drivers/md/raid10.c:928! [63010.819778] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [63010.825011] CPU: 3 PID: 44437 Comm: md0_resync Kdump: loaded Not tainted 5.14.0-86.el9.x86_64 #1 [63010.833789] Hardware name: Dell Inc. PowerEdge R6415/07YXFK, BIOS 1.15.0 09/11/2020 [63010.841440] RIP: 0010:raise_barrier+0x161/0x170 [raid10] [63010.865508] RSP: 0018:ffffc312408bbc10 EFLAGS: 00010246 [63010.870734] RAX: 0000000000000000 RBX: ffffa00bf7d39800 RCX: 0000000000000000 [63010.877866] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffa00bf7d39800 [63010.884999] RBP: 0000000000000000 R08: fffffa4945e74400 R09: 0000000000000000 [63010.892132] R10: ffffa00eed02f798 R11: 0000000000000000 R12: ffffa00bbc435200 [63010.899266] R13: ffffa00bf7d39800 R14: 0000000000000400 R15: 0000000000000003 [63010.906399] FS: 0000000000000000(0000) GS:ffffa00eed000000(0000) knlGS:0000000000000000 [63010.914485] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [63010.920229] CR2: 00007f5cfbe99828 CR3: 0000000105efe000 CR4: 00000000003506e0 [63010.927363] Call Trace: [63010.929822] ? bio_reset+0xe/0x40 [63010.933144] ? raid10_alloc_init_r10buf+0x60/0xa0 [raid10] [63010.938629] raid10_sync_request+0x756/0x1610 [raid10] [63010.943770] md_do_sync.cold+0x3e4/0x94c [63010.947698] md_thread+0xab/0x160 [63010.951024] ? md_write_inc+0x50/0x50 [63010.954688] kthread+0x149/0x170 [63010.957923] ? set_kthread_struct+0x40/0x40 [63010.962107] ret_from_fork+0x22/0x30
Removing the code that sets mddev->private to NULL in raid0 can fix problem.
--- drivers/md/raid0.c | 1 - 1 file changed, 1 deletion(-)
drivers/md/raid0.c +0 -1
@@ -361,7 +361,6 @@ static void free_conf(struct mddev *mddekfree (conf->strip_zone);kfree (conf->devlist);kfree (conf); - mddev->private =NULL ; }static void raid0_free (struct mddev *mddev,void *priv)
Greg Kroah-Hartman
maintainerPATCH 876/879 md: fix double free of io_acct_set bioset
In reply to Greg Kroah-HartmanFrom: Xiao Ni <[email protected]>
commit 42b805af102471f53e3c7867b8c2b502ea4eef7e upstream.
Now io_acct_set is alloc and free in personality. Remove the codes that free io_acct_set in md_free and md_stop.
--- drivers/md/md.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/md/md.c +0 -4
@@ -5598,8 +5598,6 @@ static void md_free(struct kobject *ko)bioset_exit (&mddev->bio_set);bioset_exit (&mddev->sync_set); -if (mddev->level !=1 && mddev->level !=10 ) -bioset_exit (&mddev->io_acct_set);kfree (mddev); }
@@ -6286,8 +6284,6 @@ void md_stop(struct mddev *mddev)__md_stop (mddev);bioset_exit (&mddev->bio_set);bioset_exit (&mddev->sync_set); -if (mddev->level !=1 && mddev->level !=10 ) -bioset_exit (&mddev->io_acct_set); }EXPORT_SYMBOL_GPL (md_stop);
Greg Kroah-Hartman
maintainerPATCH 877/879 md: bcache: check the return value of kzalloc() in detached_dev_do_request()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
commit 40f567bbb3b0639d2ec7d1c6ad4b1b018f80cf19 upstream.
The function kzalloc() in detached_dev_do_request() can fail, so its return value should be checked.
--- drivers/md/bcache/request.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/md/bcache/request.c +6 -0
@@ -1105,6 +1105,12 @@ static void detached_dev_do_request(stru* which would call closure_get(&dc->disk.cl) */ ddip =kzalloc (sizeof (struct detached_dev_io_private ),GFP_NOIO ); +if (!ddip) { + bio->bi_status =BLK_STS_RESOURCE ; + bio->bi_end_io (bio); +return ; + } + ddip->d = d;/* Count on the bcache device */ ddip->orig_bdev = orig_bdev;
Greg Kroah-Hartman
maintainerPATCH 878/879 macsec: fix UAF bug for real_dev
In reply to Greg Kroah-HartmanFrom: Ziyang Xuan <[email protected]>
commit 196a888ca6571deb344468e1d7138e3273206335 upstream.
Create a new macsec device but not get reference to real_dev. That can not ensure that real_dev is freed after macsec. That will trigger the UAF bug for real_dev as following:
==================================================================
BUG: KASAN: use-after-free in macsec_get_iflink+0x5f/0x70 drivers/net/macsec.c:3662 Call Trace: ... macsec_get_iflink+0x5f/0x70 drivers/net/macsec.c:3662 dev_get_iflink+0x73/0xe0 net/core/dev.c:637 default_operstate net/core/link_watch.c:42 [inline] rfc2863_policy+0x233/0x2d0 net/core/link_watch.c:54 linkwatch_do_dev+0x2a/0x150 net/core/link_watch.c:161 Allocated by task 22209: ... alloc_netdev_mqs+0x98/0x1100 net/core/dev.c:10549 rtnl_create_link+0x9d7/0xc00 net/core/rtnetlink.c:3235 veth_newlink+0x20e/0xa90 drivers/net/veth.c:1748 Freed by task 8: ... kfree+0xd6/0x4d0 mm/slub.c:4552 kvfree+0x42/0x50 mm/util.c:615 device_release+0x9f/0x240 drivers/base/core.c:2229 kobject_cleanup lib/kobject.c:673 [inline] kobject_release lib/kobject.c:704 [inline] kref_put include/linux/kref.h:65 [inline] kobject_put+0x1c8/0x540 lib/kobject.c:721 netdev_run_todo+0x72e/0x10b0 net/core/dev.c:10327
After commit faab39f63c1f ("net: allow out-of-order netdev unregistration") and commit e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"), we can add dev_hold_track() in macsec_dev_init() and dev_put_track() in macsec_free_netdev() to fix the problem.
--- drivers/net/macsec.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/macsec.c +7 -0
@@ -99,6 +99,7 @@ struct pcpu_secy_stats {* struct macsec_dev - private data * @secy: SecY config * @real_dev: pointer to underlying netdevice +* @dev_tracker: refcount tracker for @real_dev reference * @stats: MACsec device stats * @secys: linked list of SecY's on the underlying device * @gro_cells: pointer to the Generic Receive Offload cell
@@ -107,6 +108,7 @@ struct pcpu_secy_stats {struct macsec_dev {struct macsec_secy secy;struct net_device *real_dev; +netdevice_tracker dev_tracker;struct pcpu_secy_stats __percpu *stats;struct list_head secys;struct gro_cells gro_cells;
@@ -3459,6 +3461,9 @@ static int macsec_dev_init(struct net_deif (is_zero_ether_addr (dev->broadcast))memcpy (dev->broadcast, real_dev->broadcast, dev->addr_len); +/* Get macsec's reference to real_dev */ +dev_hold_track (real_dev, &macsec->dev_tracker,GFP_KERNEL ); +return 0 ; }
@@ -3704,6 +3709,8 @@ static void macsec_free_netdev(struct nefree_percpu (macsec->stats);free_percpu (macsec->secy.tx_sc.stats); +/* Get rid of the macsec's reference to real_dev */ +dev_put_track (macsec->real_dev, &macsec->dev_tracker); }static void macsec_setup (struct net_device *dev)
Greg Kroah-Hartman
maintainerPATCH 879/879 tty: n_gsm: Fix packet data hex dump output
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
commit 925ea0fa5277c1e6bb9e51955ef34eea9736c3d7 upstream.
The module param debug for n_gsm uses KERN_INFO level, but the hexdump now uses KERN_DEBUG level. This started after commit 091cb0994edd ("lib/hexdump: make print_hex_dump_bytes() a nop on !DEBUG builds"). We now use dynamic_hex_dump() unless DEBUG is set.
This causes no packets to be seen with modprobe n_gsm debug=0x1f unlike earlier. Let's fix this by adding gsm_hex_dump_bytes() that calls print_hex_dump() with KERN_INFO to match what n_gsm is doing with the other debug related output.
--- drivers/tty/n_gsm.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)
drivers/tty/n_gsm.c +23 -8
@@ -444,6 +444,25 @@ static u8 gsm_encode_modem(const structreturn modembits; } +static void gsm_hex_dump_bytes (const char *fname,const u8 *data, +unsigned long len) +{ +char *prefix; + +if (!fname) { +print_hex_dump (KERN_INFO ,"" ,DUMP_PREFIX_NONE ,16 ,1 , data, len, + true); +return ; + } + + prefix =kasprintf (GFP_KERNEL ,"%s: " , fname); +if (!prefix) +return ; +print_hex_dump (KERN_INFO , prefix,DUMP_PREFIX_OFFSET ,16 ,1 , data, len, + true); +kfree (prefix); +} +/** * gsm_print_packet - display a frame for debug * @hdr: header to print before decode
@@ -508,7 +527,7 @@ static void gsm_print_packet(const charelse pr_cont ("(F)" ); -print_hex_dump_bytes ("" ,DUMP_PREFIX_NONE , data, dlen); +gsm_hex_dump_bytes (NULL , data, dlen); }
@@ -698,9 +717,7 @@ static void gsm_data_kick(struct gsm_mux }if (debug &4 ) -print_hex_dump_bytes ("gsm_data_kick: " , -DUMP_PREFIX_OFFSET , - gsm->txframe, len); +gsm_hex_dump_bytes (__func__, gsm->txframe, len);if (gsmld_output (gsm, gsm->txframe, len) <=0 )break ;/* FIXME: Can eliminate one SOF in many more cases */
@@ -2448,8 +2465,7 @@ static int gsmld_output(struct gsm_mux *return -ENOSPC ; }if (debug &4 ) -print_hex_dump_bytes ("gsmld_output: " ,DUMP_PREFIX_OFFSET , - data, len); +gsm_hex_dump_bytes (__func__, data, len);return gsm->tty->ops->write (gsm->tty, data, len); }
@@ -2525,8 +2541,7 @@ static void gsmld_receive_buf(struct ttychar flags =TTY_NORMAL ;if (debug &4 ) -print_hex_dump_bytes ("gsmld_receive: " ,DUMP_PREFIX_OFFSET , - cp, count); +gsm_hex_dump_bytes (__func__, cp, count);for (; count; count--, cp++) {if (fp)
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.thanks,
greg k-h
Hi Greg,
Compiled and booted on my test system Lenovo P50s: Intel Core i7 No emergency and critical messages in the dmesg
./perf bench sched all
# Running sched/messaging benchmark...
# 20 sender and receiver processes per group
# 10 groups == 400 processes run
Total time: 0.447 [sec]
# Running sched/pipe benchmark...
# Executed 1000000 pipe operations between two processes
Total time: 10.055 [sec]
10.055368 usecs/op
99449 ops/secThanks
-Zan
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Hey Greg,
Ran tests and boot tested on my system, no regressions found
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 5.18.3-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.18.y
* git commit: 09bf95a7c28a7069eb8bb958d434a575a0c63454
* git describe: v5.18.2-880-g09bf95a7c28a
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.18.y/build/v5.18.2-880-g09bf95a7c28a
## Test Regressions (compared to v5.18.2)
No test regressions found.
## Metric Regressions (compared to v5.18.2)
No metric regressions found.
## Test Fixes (compared to v5.18.2)
No test fixes found.
## Metric Fixes (compared to v5.18.2)
No metric fixes found.
## Test result summary
total: 136450, pass: 124786, fail: 519, skip: 10295, xfail: 850
## Build Summary
* arm: 17 total, 14 passed, 3 failed
* arm64: 20 total, 18 passed, 2 failed
* i386: 17 total, 12 passed, 5 failed
* mips: 4 total, 1 passed, 3 failed
* parisc: 2 total, 2 passed, 0 failed
* powerpc: 5 total, 2 passed, 3 failed
* riscv: 5 total, 5 passed, 0 failed
* s390: 5 total, 2 passed, 3 failed
* sh: 2 total, 0 passed, 2 failed
* sparc: 2 total, 2 passed, 0 failed
* x86_64: 20 total, 17 passed, 3 failed
## Test suites summary
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers-dma-buf
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-firmware
* kselftest-fpu
* kselftest-gpio
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-lib
* kselftest-membarrier
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-zram
* kunit
* kunit/15
* kunit/261
* kunit/3
* kunit/427
* kunit/90
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-cap_bounds-tests
* ltp-commands
* ltp-commands-tests
* ltp-containers
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto
* ltp-crypto-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests
* ltp-fcntl-locktests-tests
* ltp-filecaps
* ltp-filecaps-tests
* ltp-fs
* ltp-fs-tests
* ltp-fs_bind
* ltp-fs_bind-tests
* ltp-fs_perms_simple
* ltp-fs_perms_simple-tests
* ltp-fsx
* ltp-fsx-tests
* ltp-hugetlb
* ltp-hugetlb-tests
* ltp-io
* ltp-io-tests
* ltp-ipc
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* packetdrill
* perf
* rcutorture
* ssuite
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.thanks,
greg k-h
5.18.3-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.thanks,
greg k-h
Tested rc1 against the Fedora build system (aarch64, armv7, ppc64le, s390x, x86_64), and boot tested x86_64. No regressions noted.
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
Build results:
total: 154 pass: 154 fail: 0 Qemu test results: total: 489 pass: 489 fail: 0
Guenter
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully cross-compiled for arm (multi_v7_defconfig, GCC 12.1.0, armv7 with neon fpu) and arm64 (bcm2711_defconfig, GCC 12.1.0).
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.18.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.18.y
and the diffstat can be found below.
openSUSE configs¹⁾ all green.
¹⁾ armv6hl armv7hl arm64 i386 ppc64 ppc64le riscv64 s390x x86_64
Signature · 2 lines
js suse labs