6.6.66-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 254/356 bpf: Call free_htab_elem() after htab_unlock_bucket()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao <[email protected]>
[ Upstream commit b9e9ed90b10c82a4e9d4d70a2890f06bfcdd3b78 ]
For htab of maps, when the map is removed from the htab, it may hold the last reference of the map. bpf_map_fd_put_ptr() will invoke bpf_map_free_id() to free the id of the removed map element. However, bpf_map_fd_put_ptr() is invoked while holding a bucket lock (raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock (spinlock_t), triggering the following lockdep warning:
=============================
[ BUG: Invalid wait context ]
6.11.0-rc4+ #49 Not tainted
-----------------------------
test_maps/4881 is trying to lock:
ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this:
context-{5:5}
2 locks held by test_maps/4881:
#0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80
stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7e
One way to fix the lockdep warning is using raw_spinlock_t for map_idr_lock as well. However, bpf_map_alloc_id() invokes idr_alloc_cyclic() after acquiring map_idr_lock, it will trigger a similar lockdep warning because the slab's lock (s->cpu_slab->lock) is still a spinlock.
Instead of changing map_idr_lock's type, fix the issue by invoking htab_put_fd_value() after htab_unlock_bucket(). However, only deferring the invocation of htab_put_fd_value() is not enough, because the old map pointers in htab of maps can not be saved during batched deletion. Therefore, also defer the invocation of free_htab_elem(), so these to-be-freed elements could be linked together similar to lru map.
There are four callers for ->map_fd_put_ptr:
(1) alloc_htab_elem() (through htab_put_fd_value())
It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation of htab_put_fd_value() can not simply move after htab_unlock_bucket(), because the old element has already been stashed in htab->extra_elems. It may be reused immediately after htab_unlock_bucket() and the invocation of htab_put_fd_value() after htab_unlock_bucket() may release the newly-added element incorrectly. Therefore, saving the map pointer of the old element for htab of maps before unlocking the bucket and releasing the map_ptr after unlock. Beside the map pointer in the old element, should do the same thing for the special fields in the old element as well.
(2) free_htab_elem() (through htab_put_fd_value())
Its caller includes __htab_map_lookup_and_delete_elem(), htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().
For htab_map_delete_elem(), simply invoke free_htab_elem() after htab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), just like lru map, linking the to-be-freed element into node_to_free list and invoking free_htab_elem() for these element after unlock. It is safe to reuse batch_flink as the link for node_to_free, because these elements have been removed from the hash llist.
Because htab of maps doesn't support lookup_and_delete operation, __htab_map_lookup_and_delete_elem() doesn't have the problem, so kept it as is.
(3) fd_htab_map_free()
It invokes ->map_fd_put_ptr without raw_spinlock_t.
(4) bpf_fd_htab_map_update_elem()
It invokes ->map_fd_put_ptr without raw_spinlock_t.
After moving free_htab_elem() outside htab bucket lock scope, using pcpu_freelist_push() instead of __pcpu_freelist_push() to disable the irq before freeing elements, and protecting the invocations of bpf_mem_cache_free() with migrate_{disable|enable} pair.
--- kernel/bpf/hashtab.c | 56 ++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 17 deletions(-)
kernel/bpf/hashtab.c +39 -17
@@ -892,9 +892,12 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)static void htab_elem_free (struct bpf_htab *htab,struct htab_elem *l) {check_and_free_fields (htab, l); + +migrate_disable ();if (htab->map.map_type ==BPF_MAP_TYPE_PERCPU_HASH )bpf_mem_cache_free (&htab->pcpu_ma, l->ptr_to_pptr);bpf_mem_cache_free (&htab->ma, l); +migrate_enable (); }static void htab_put_fd_value (struct bpf_htab *htab,struct htab_elem *l)
@@ -944,7 +947,7 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)if (htab_is_prealloc (htab)) {bpf_map_dec_elem_count (&htab->map);check_and_free_fields (htab, l); -__pcpu_freelist_push (&htab->freelist, &l->fnode); +pcpu_freelist_push (&htab->freelist, &l->fnode); }else {dec_elem_count (htab);htab_elem_free (htab, l);
@@ -1014,7 +1017,6 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,*/ pl_new =this_cpu_ptr (htab->extra_elems); l_new = *pl_new; -htab_put_fd_value (htab, old_elem); *pl_new = old_elem; }else {struct pcpu_freelist_node *l;
@@ -1100,6 +1102,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,struct htab_elem *l_new =NULL , *l_old;struct hlist_nulls_head *head;unsigned long flags; +void *old_map_ptr;struct bucket *b;u32 key_size, hash;int ret;
@@ -1178,12 +1181,27 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,hlist_nulls_add_head_rcu (&l_new->hash_node, head);if (l_old) {hlist_nulls_del_rcu (&l_old->hash_node); + +/* l_old has already been stashed in htab->extra_elems, free +* its special fields before it is available for reuse. Also +* save the old map pointer in htab of maps before unlock +* and release it after unlock. +*/ + old_map_ptr =NULL ; +if (htab_is_prealloc (htab)) { +if (map->ops->map_fd_put_ptr) + old_map_ptr =fd_htab_map_get_ptr (map, l_old); +check_and_free_fields (htab, l_old); + } + } +htab_unlock_bucket (htab, b, hash, flags); +if (l_old) { +if (old_map_ptr) + map->ops->map_fd_put_ptr (map, old_map_ptr, true);if (!htab_is_prealloc (htab))free_htab_elem (htab, l_old); -else -check_and_free_fields (htab, l_old); } - ret =0 ; +return 0 ; err:htab_unlock_bucket (htab, b, hash, flags);return ret;
@@ -1427,15 +1445,15 @@ static long htab_map_delete_elem(struct bpf_map *map, void *key)return ret; l =lookup_elem_raw (head, hash, key, key_size); - -if (l) { +if (l)hlist_nulls_del_rcu (&l->hash_node); -free_htab_elem (htab, l); - }else { +else ret = -ENOENT ; - }htab_unlock_bucket (htab, b, hash, flags); + +if (l) +free_htab_elem (htab, l);return ret; }
@@ -1842,13 +1860,14 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,* may cause deadlock. See comments in function * prealloc_lru_pop(). Let us do bpf_lru_push_free() * after releasing the bucket lock. +* +* For htab of maps, htab_put_fd_value() in +* free_htab_elem() may acquire a spinlock with bucket +* lock being held and it violates the lock rule, so +* invoke free_htab_elem() after unlock as well. */ -if (is_lru_map) { - l->batch_flink = node_to_free; - node_to_free = l; - }else { -free_htab_elem (htab, l); - } + l->batch_flink = node_to_free; + node_to_free = l; } dst_key += key_size; dst_val += value_size;
@@ -1860,7 +1879,10 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,while (node_to_free) { l = node_to_free; node_to_free = node_to_free->batch_flink; -htab_lru_push_free (htab, l); +if (is_lru_map) +htab_lru_push_free (htab, l); +else +free_htab_elem (htab, l); } next_batch:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 255/356 dsa: qca8k: Use nested lock to avoid splat
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Lunn <[email protected]>
[ Upstream commit 078e0d596f7b5952dad8662ace8f20ed2165e2ce ]
qca8k_phy_eth_command() is used to probe the child MDIO bus while the parent MDIO is locked. This causes lockdep splat, reporting a possible deadlock. It is not an actually deadlock, because different locks are used. By making use of mutex_lock_nested() we can avoid this false positive.
--- drivers/net/dsa/qca/qca8k-8xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/qca/qca8k-8xxx.c +1 -1
@@ -673,7 +673,7 @@ qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,* We therefore need to lock the MDIO bus onto which the switch is * connected. */ -mutex_lock (&priv->bus->mdio_lock); +mutex_lock_nested (&priv->bus->mdio_lock,MDIO_MUTEX_NESTED );/* Actually start the request: * 1. Send mdio master packet
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 256/356 Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hilda Wu <[email protected]>
[ Upstream commit 69b84ffce260ff13826dc10aeb3c3e5c2288a552 ]
Add the support ID 0489:e123 to usb_device_id table for Realtek RTL8852B chip.
The device info from /sys/kernel/debug/usb/devices as below.
T: Bus=01 Lev=01 Prnt=01 Port=07 Cnt=04 Dev#= 7 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e123 Rev= 0.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
--- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -555,6 +555,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe123), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 257/356 Bluetooth: hci_core: Fix not checking skb length on hci_acldata_packet
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 3fe288a8214e7dd784d1f9b7c9e448244d316b47 ]
This fixes not checking if skb really contains an ACL header otherwise the code may attempt to access some uninitilized/invalid memory past the valid skb->data.
--- net/bluetooth/hci_core.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/bluetooth/hci_core.c +9 -4
@@ -3735,18 +3735,22 @@ static void hci_tx_work(struct work_struct *work)/* ACL data packet */ static void hci_acldata_packet (struct hci_dev *hdev,struct sk_buff *skb) { -struct hci_acl_hdr *hdr = (void *) skb->data; +struct hci_acl_hdr *hdr;struct hci_conn *conn;__u16 handle, flags; -skb_pull (skb,HCI_ACL_HDR_SIZE ); + hdr =skb_pull_data (skb,sizeof (*hdr)); +if (!hdr) { +bt_dev_err (hdev,"ACL packet too small" ); + goto drop; + } handle =__le16_to_cpu (hdr->handle); flags =hci_flags (handle); handle =hci_handle (handle); -BT_DBG ("%s len %d handle 0x%4.4x flags 0x%4.4x" , hdev->name, skb->len, - handle, flags); +bt_dev_dbg (hdev,"len %d handle 0x%4.4x flags 0x%4.4x" , skb->len, + handle, flags); hdev->stat.acl_rx++;
@@ -3765,6 +3769,7 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) handle); } +drop:kfree_skb (skb); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 258/356 Bluetooth: Add new quirks for ATS2851
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danil Pylaev <[email protected]>
[ Upstream commit 94464a7b71634037b13d54021e0dfd0fb0d8c1f0 ]
This adds quirks for broken extended create connection, and write auth payload timeout.
--- include/net/bluetooth/hci.h | 14 ++++++++++++++ include/net/bluetooth/hci_core.h | 10 ++++++---- 2 files changed, 20 insertions(+), 4 deletions(-)
include/net/bluetooth/hci.h +14 -0
@@ -297,6 +297,20 @@ enum {*/ HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT , +/* +* When this quirk is set, the HCI_OP_LE_EXT_CREATE_CONN command is +* disabled. This is required for the Actions Semiconductor ATS2851 +* based controllers, which erroneously claims to support it. +*/ +HCI_QUIRK_BROKEN_EXT_CREATE_CONN , + +/* +* When this quirk is set, the command WRITE_AUTH_PAYLOAD_TIMEOUT is +* skipped. This is required for the Actions Semiconductor ATS2851 +* based controllers, due to a race condition in pairing process. +*/ +HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT , +/* When this quirk is set, MSFT extension monitor tracking by * address filter is supported. Since tracking quantity of each * pattern is limited, this feature supports tracking multiple
include/net/bluetooth/hci_core.h +6 -4
@@ -1852,8 +1852,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn); !test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks))/* Use ext create connection if command is supported */ -#define use_ext_conn (dev) ((dev)->commands[37] & 0x80) - +#define use_ext_conn (dev) (((dev)->commands[37] & 0x80) && \ + !test_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, &(dev)->quirks))/* Extended advertising support */ #define ext_adv_capable (dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV))
@@ -1866,8 +1866,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);* C24: Mandatory if the LE Controller supports Connection State and either * LE Feature (LL Privacy) or LE Feature (Extended Advertising) is supported */ -#define use_enhanced_conn_complete (dev) (ll_privacy_capable(dev) || \ - ext_adv_capable(dev)) +#define use_enhanced_conn_complete (dev) ((ll_privacy_capable(dev) || \ + ext_adv_capable(dev)) && \ + !test_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, \ + &(dev)->quirks))/* Periodic advertising support */ #define per_adv_capable (dev) (((dev)->le_features[1] & HCI_LE_PERIODIC_ADV))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 259/356 Bluetooth: Support new quirks for ATS2851
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danil Pylaev <[email protected]>
[ Upstream commit 5bd3135924b4570dcecc8793f7771cb8d42d8b19 ]
This adds support for quirks for broken extended create connection, and write auth payload timeout.
--- net/bluetooth/hci_event.c | 7 +++++++ net/bluetooth/hci_sync.c | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-)
net/bluetooth/hci_event.c +7 -0
@@ -3627,6 +3627,13 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data, goto unlock; } +/* We skip the WRITE_AUTH_PAYLOAD_TIMEOUT for ATS2851 based controllers +* to avoid unexpected SMP command errors when pairing. +*/ +if (test_bit (HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT , + &hdev->quirks)) + goto notify; +/* Set the default Authenticated Payload Timeout after * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be
net/bluetooth/hci_sync.c +8 -1
@@ -4853,6 +4853,13 @@ static const struct {HCI_QUIRK_BROKEN (SET_RPA_TIMEOUT ,"HCI LE Set Random Private Address Timeout command is " "advertised, but not supported." ), +HCI_QUIRK_BROKEN (EXT_CREATE_CONN , +"HCI LE Extended Create Connection command is " +"advertised, but not supported." ), +HCI_QUIRK_BROKEN (WRITE_AUTH_PAYLOAD_TIMEOUT , +"HCI WRITE AUTH PAYLOAD TIMEOUT command leads " +"to unexpected SMP errors when pairing " +"and will not be used." ),HCI_QUIRK_BROKEN (LE_CODED ,"HCI LE Coded PHY feature bit is set, " "but its usage is not supported." )
@@ -6485,7 +6492,7 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data) &own_addr_type);if (err) goto done; - +/* Send command LE Extended Create Connection if supported */ if (use_ext_conn (hdev)) { err =hci_le_ext_create_conn_sync (hdev, conn, own_addr_type); goto done;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 260/356 Bluetooth: Set quirks for ATS2851
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danil Pylaev <[email protected]>
[ Upstream commit 677a55ba11a82c2835550a82324cec5fcb2f9e2d ]
This adds quirks for broken ats2851 features.
--- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -4490,6 +4490,8 @@ static int btusb_probe(struct usb_interface *intf,set_bit (HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT , &hdev->quirks);set_bit (HCI_QUIRK_BROKEN_EXT_SCAN , &hdev->quirks);set_bit (HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE , &hdev->quirks); +set_bit (HCI_QUIRK_BROKEN_EXT_CREATE_CONN , &hdev->quirks); +set_bit (HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT , &hdev->quirks); }if (!reset)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 261/356 ASoC: hdmi-codec: reorder channel allocation list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Karlman <[email protected]>
[ Upstream commit 82ff5abc2edcfba0c0f1a1be807795e2876f46e9 ]
The ordering in hdmi_codec_get_ch_alloc_table_idx() results in wrong channel allocation for a number of cases, e.g. when ELD reports FL|FR|LFE|FC|RL|RR or FL|FR|LFE|FC|RL|RR|RC|RLC|RRC:
ca_id 0x01 with speaker mask FL|FR|LFE is selected instead of ca_id 0x03 with speaker mask FL|FR|LFE|FC for 4 channels
and
ca_id 0x04 with speaker mask FL|FR|RC gets selected instead of ca_id 0x0b with speaker mask FL|FR|LFE|FC|RL|RR for 6 channels
Fix this by reordering the channel allocation list with most specific speaker masks at the top.
--- sound/soc/codecs/hdmi-codec.c | 140 +++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 63 deletions(-)
sound/soc/codecs/hdmi-codec.c +77 -63
@@ -184,84 +184,97 @@ static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {/* * hdmi_codec_channel_alloc: speaker configuration available for CEA * -* This is an ordered list that must match with hdmi_codec_8ch_chmaps struct +* This is an ordered list where ca_id must exist in hdmi_codec_8ch_chmaps * The preceding ones have better chances to be selected by * hdmi_codec_get_ch_alloc_table_idx(). */ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { { .ca_id =0x00 , .n_ch =2 , - .mask =FL |FR }, -/* 2.1 */ - { .ca_id =0x01 , .n_ch =4 , - .mask =FL |FR |LFE }, -/* Dolby Surround */ + .mask =FL |FR }, + { .ca_id =0x03 , .n_ch =4 , + .mask =FL |FR |LFE |FC }, { .ca_id =0x02 , .n_ch =4 , .mask =FL |FR |FC }, -/* surround51 */ + { .ca_id =0x01 , .n_ch =4 , + .mask =FL |FR |LFE }, { .ca_id =0x0b , .n_ch =6 , - .mask =FL |FR |LFE |FC |RL |RR }, -/* surround40 */ - { .ca_id =0x08 , .n_ch =6 , - .mask =FL |FR |RL |RR }, -/* surround41 */ - { .ca_id =0x09 , .n_ch =6 , - .mask =FL |FR |LFE |RL |RR }, -/* surround50 */ + .mask =FL |FR |LFE |FC |RL |RR }, { .ca_id =0x0a , .n_ch =6 , .mask =FL |FR |FC |RL |RR }, -/* 6.1 */ - { .ca_id =0x0f , .n_ch =8 , - .mask =FL |FR |LFE |FC |RL |RR |RC }, -/* surround71 */ + { .ca_id =0x09 , .n_ch =6 , + .mask =FL |FR |LFE |RL |RR }, + { .ca_id =0x08 , .n_ch =6 , + .mask =FL |FR |RL |RR }, + { .ca_id =0x07 , .n_ch =6 , + .mask =FL |FR |LFE |FC |RC }, + { .ca_id =0x06 , .n_ch =6 , + .mask =FL |FR |FC |RC }, + { .ca_id =0x05 , .n_ch =6 , + .mask =FL |FR |LFE |RC }, + { .ca_id =0x04 , .n_ch =6 , + .mask =FL |FR |RC }, { .ca_id =0x13 , .n_ch =8 , .mask =FL |FR |LFE |FC |RL |RR |RLC |RRC }, -/* others */ - { .ca_id =0x03 , .n_ch =8 , - .mask =FL |FR |LFE |FC }, - { .ca_id =0x04 , .n_ch =8 , - .mask =FL |FR |RC }, - { .ca_id =0x05 , .n_ch =8 , - .mask =FL |FR |LFE |RC }, - { .ca_id =0x06 , .n_ch =8 , - .mask =FL |FR |FC |RC }, - { .ca_id =0x07 , .n_ch =8 , - .mask =FL |FR |LFE |FC |RC }, - { .ca_id =0x0c , .n_ch =8 , - .mask =FL |FR |RC |RL |RR }, - { .ca_id =0x0d , .n_ch =8 , - .mask =FL |FR |LFE |RL |RR |RC }, - { .ca_id =0x0e , .n_ch =8 , - .mask =FL |FR |FC |RL |RR |RC }, - { .ca_id =0x10 , .n_ch =8 , - .mask =FL |FR |RL |RR |RLC |RRC }, - { .ca_id =0x11 , .n_ch =8 , - .mask =FL |FR |LFE |RL |RR |RLC |RRC }, + { .ca_id =0x1f , .n_ch =8 , + .mask =FL |FR |LFE |FC |RL |RR |FLC |FRC }, { .ca_id =0x12 , .n_ch =8 , .mask =FL |FR |FC |RL |RR |RLC |RRC }, - { .ca_id =0x14 , .n_ch =8 , - .mask =FL |FR |FLC |FRC }, - { .ca_id =0x15 , .n_ch =8 , - .mask =FL |FR |LFE |FLC |FRC }, - { .ca_id =0x16 , .n_ch =8 , - .mask =FL |FR |FC |FLC |FRC }, - { .ca_id =0x17 , .n_ch =8 , - .mask =FL |FR |LFE |FC |FLC |FRC }, - { .ca_id =0x18 , .n_ch =8 , - .mask =FL |FR |RC |FLC |FRC }, - { .ca_id =0x19 , .n_ch =8 , - .mask =FL |FR |LFE |RC |FLC |FRC }, - { .ca_id =0x1a , .n_ch =8 , - .mask =FL |FR |RC |FC |FLC |FRC }, - { .ca_id =0x1b , .n_ch =8 , - .mask =FL |FR |LFE |RC |FC |FLC |FRC }, - { .ca_id =0x1c , .n_ch =8 , - .mask =FL |FR |RL |RR |FLC |FRC }, - { .ca_id =0x1d , .n_ch =8 , - .mask =FL |FR |LFE |RL |RR |FLC |FRC }, { .ca_id =0x1e , .n_ch =8 , .mask =FL |FR |FC |RL |RR |FLC |FRC }, - { .ca_id =0x1f , .n_ch =8 , - .mask =FL |FR |LFE |FC |RL |RR |FLC |FRC }, + { .ca_id =0x11 , .n_ch =8 , + .mask =FL |FR |LFE |RL |RR |RLC |RRC }, + { .ca_id =0x1d , .n_ch =8 , + .mask =FL |FR |LFE |RL |RR |FLC |FRC }, + { .ca_id =0x10 , .n_ch =8 , + .mask =FL |FR |RL |RR |RLC |RRC }, + { .ca_id =0x1c , .n_ch =8 , + .mask =FL |FR |RL |RR |FLC |FRC }, + { .ca_id =0x0f , .n_ch =8 , + .mask =FL |FR |LFE |FC |RL |RR |RC }, + { .ca_id =0x1b , .n_ch =8 , + .mask =FL |FR |LFE |RC |FC |FLC |FRC }, + { .ca_id =0x0e , .n_ch =8 , + .mask =FL |FR |FC |RL |RR |RC }, + { .ca_id =0x1a , .n_ch =8 , + .mask =FL |FR |RC |FC |FLC |FRC }, + { .ca_id =0x0d , .n_ch =8 , + .mask =FL |FR |LFE |RL |RR |RC }, + { .ca_id =0x19 , .n_ch =8 , + .mask =FL |FR |LFE |RC |FLC |FRC }, + { .ca_id =0x0c , .n_ch =8 , + .mask =FL |FR |RC |RL |RR }, + { .ca_id =0x18 , .n_ch =8 , + .mask =FL |FR |RC |FLC |FRC }, + { .ca_id =0x17 , .n_ch =8 , + .mask =FL |FR |LFE |FC |FLC |FRC }, + { .ca_id =0x16 , .n_ch =8 , + .mask =FL |FR |FC |FLC |FRC }, + { .ca_id =0x15 , .n_ch =8 , + .mask =FL |FR |LFE |FLC |FRC }, + { .ca_id =0x14 , .n_ch =8 , + .mask =FL |FR |FLC |FRC }, + { .ca_id =0x0b , .n_ch =8 , + .mask =FL |FR |LFE |FC |RL |RR }, + { .ca_id =0x0a , .n_ch =8 , + .mask =FL |FR |FC |RL |RR }, + { .ca_id =0x09 , .n_ch =8 , + .mask =FL |FR |LFE |RL |RR }, + { .ca_id =0x08 , .n_ch =8 , + .mask =FL |FR |RL |RR }, + { .ca_id =0x07 , .n_ch =8 , + .mask =FL |FR |LFE |FC |RC }, + { .ca_id =0x06 , .n_ch =8 , + .mask =FL |FR |FC |RC }, + { .ca_id =0x05 , .n_ch =8 , + .mask =FL |FR |LFE |RC }, + { .ca_id =0x04 , .n_ch =8 , + .mask =FL |FR |RC }, + { .ca_id =0x03 , .n_ch =8 , + .mask =FL |FR |LFE |FC }, + { .ca_id =0x02 , .n_ch =8 , + .mask =FL |FR |FC }, + { .ca_id =0x01 , .n_ch =8 , + .mask =FL |FR |LFE }, };struct hdmi_codec_priv {
@@ -370,7 +383,8 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,struct snd_pcm_chmap *info =snd_kcontrol_chip (kcontrol);struct hdmi_codec_priv *hcp = info->private_data; - map = info->chmap[hcp->chmap_idx].map; +if (hcp->chmap_idx !=HDMI_CODEC_CHMAP_IDX_UNKNOWN ) + map = info->chmap[hcp->chmap_idx].map;for (i =0 ; i < info->max_channels; i++) {if (hcp->chmap_idx ==HDMI_CODEC_CHMAP_IDX_UNKNOWN )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 262/356 rocker: fix link status detection in rocker_carrier_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit e64285ff41bb7a934bd815bd38f31119be62ac37 ]
Since '1 << rocker_port->pport' may be undefined for port >= 32, cast the left operand to 'unsigned long long' like it's done in 'rocker_port_set_enable()' above. Compile tested only.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/ethernet/rocker/rocker_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/rocker/rocker_main.c +1 -1
@@ -2504,7 +2504,7 @@ static void rocker_carrier_init(const struct rocker_port *rocker_port)u64 link_status =rocker_read64 (rocker,PORT_PHYS_LINK_STATUS );bool link_up; - link_up = link_status & (1 << rocker_port->pport); + link_up = link_status & (1ULL << rocker_port->pport);if (link_up)netif_carrier_on (rocker_port->dev);else
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 263/356 net/neighbor: clear error in case strict check is not set
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 0de6a472c3b38432b2f184bd64eb70d9ea36d107 ]
Commit 51183d233b5a ("net/neighbor: Update neigh_dump_info for strict data checking") added strict checking. The err variable is not cleared, so if we find no table to dump we will return the validation error even if user did not want strict checking.
I think the only way to hit this is to send an buggy request, and ask for a table which doesn't exist, so there's no point treating this as a real fix. I only noticed it because a syzbot repro depended on it to trigger another bug.
--- net/core/neighbour.c | 1 + 1 file changed, 1 insertion(+)
net/core/neighbour.c +1 -0
@@ -2875,6 +2875,7 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) err =neigh_valid_dump_req (nlh, cb->strict_check, &filter, cb->extack);if (err <0 && cb->strict_check)return err; + err =0 ; s_t = cb->args[0 ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 264/356 netpoll: Use rcu_access_pointer() in __netpoll_setup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit c69c5e10adb903ae2438d4f9c16eccf43d1fcbc1 ]
The ndev->npinfo pointer in __netpoll_setup() is RCU-protected but is being accessed directly for a NULL check. While no RCU read lock is held in this context, we should still use proper RCU primitives for consistency and correctness.
Replace the direct NULL check with rcu_access_pointer(), which is the appropriate primitive when only checking for NULL without dereferencing the pointer. This function provides the necessary ordering guarantees without requiring RCU read-side protection.
--- net/core/netpoll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/netpoll.c +1 -1
@@ -633,7 +633,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) goto out; } -if (!ndev->npinfo) { +if (!rcu_access_pointer (ndev->npinfo)) { npinfo =kmalloc (sizeof (*npinfo),GFP_KERNEL );if (!npinfo) { err = -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 265/356 pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esben Haabendal <[email protected]>
[ Upstream commit 58414a31c5713afb5449fd74a26a843d34cc62e8 ]
When PINCTRL_IMX_SCU was selected by PINCTRL_IMX8DXL or PINCTRL_IMX8QM combined with COMPILE_TEST on a non-arm platforms, the IMX_SCU dependency could not be enabled.
--- drivers/pinctrl/freescale/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/freescale/Kconfig +1 -1
@@ -9,7 +9,7 @@ config PINCTRL_IMX config PINCTRL_IMX_SCU tristate - depends on IMX_SCU + depends on IMX_SCU || COMPILE_TEST select PINCTRL_IMX config PINCTRL_IMX1_CORE
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 266/356 tracing/ftrace: disable preemption in syscall probe
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathieu Desnoyers <[email protected]>
[ Upstream commit 13d750c2c03e9861e15268574ed2c239cca9c9d5 ]
In preparation for allowing system call enter/exit instrumentation to handle page faults, make sure that ftrace can handle this change by explicitly disabling preemption within the ftrace system call tracepoint probes to respect the current expectations within ftrace ring buffer code.
This change does not yet allow ftrace to take page faults per se within its probe, but allows its existing probes to adapt to the upcoming change.
--- include/trace/trace_events.h | 36 +++++++++++++++++++++++++++++++---- kernel/trace/trace_syscalls.c | 12 ++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-)
include/trace/trace_events.h +32 -4
@@ -244,6 +244,9 @@ static struct trace_event_fields trace_event_fields_##call[] = { \ tstruct \ {} }; +#undef DECLARE_EVENT_SYSCALL_CLASS +#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS +#undef DEFINE_EVENT_PRINT#define DEFINE_EVENT_PRINT (template, name, proto, args, print)
@@ -374,11 +377,11 @@ static inline notrace int trace_event_get_offsets_##call( \#include "stages/stage6_event_callback.h" -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS (call, proto, args, tstruct, assign, print) \ - \ + +#undef __DECLARE_EVENT_CLASS +#define __DECLARE_EVENT_CLASS (call, proto, args, tstruct, assign, print) \ static notrace void \ -trace_event_raw_event_##call(void *__data, proto) \ +do_trace_event_raw_event_##call(void *__data, proto) \ { \ struct trace_event_file *trace_file = __data; \ struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
@@ -403,6 +406,29 @@ trace_event_raw_event_##call(void *__data, proto) \ \trace_event_buffer_commit (&fbuffer); \ } + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS (call, proto, args, tstruct, assign, print) \ +__DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \ + PARAMS(assign), PARAMS(print)) \ +static notrace void \ +trace_event_raw_event_##call(void *__data, proto) \ +{ \ + do_trace_event_raw_event_##call(__data, args); \ +} + +#undef DECLARE_EVENT_SYSCALL_CLASS +#define DECLARE_EVENT_SYSCALL_CLASS (call, proto, args, tstruct, assign, print) \ +__DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \ + PARAMS(assign), PARAMS(print)) \ +static notrace void \ +trace_event_raw_event_##call(void *__data, proto) \ +{ \ + preempt_disable_notrace(); \ + do_trace_event_raw_event_##call(__data, args); \ + preempt_enable_notrace(); \ +} +/* * The ftrace_test_probe is compiled out, it is only here as a build time check * to make sure that if the tracepoint handling changes, the ftrace probe will
@@ -418,6 +444,8 @@ static inline void ftrace_test_probe_##call(void) \#include TRACE_INCLUDE (TRACE_INCLUDE_FILE ) +#undef __DECLARE_EVENT_CLASS +#include "stages/stage7_class_define.h" #undef DECLARE_EVENT_CLASS
kernel/trace/trace_syscalls.c +12 -0
@@ -299,6 +299,12 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)int syscall_nr;int size; +/* +* Syscall probe called with preemption enabled, but the ring +* buffer and per-cpu data require preemption to be disabled. +*/ +guard (preempt_notrace)(); + syscall_nr =trace_get_syscall_nr (current, regs);if (syscall_nr <0 || syscall_nr >= NR_syscalls)return ;
@@ -338,6 +344,12 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)struct trace_event_buffer fbuffer;int syscall_nr; +/* +* Syscall probe called with preemption enabled, but the ring +* buffer and per-cpu data require preemption to be disabled. +*/ +guard (preempt_notrace)(); + syscall_nr =trace_get_syscall_nr (current, regs);if (syscall_nr <0 || syscall_nr >= NR_syscalls)return ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 267/356 tracing: Use atomic64_inc_return() in trace_clock_counter()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uros Bizjak <[email protected]>
[ Upstream commit eb887c4567d1b0e7684c026fe7df44afa96589e6 ]
Use atomic64_inc_return(&ref) instead of atomic64_add_return(1, &ref) to use optimized implementation and ease register pressure around the primitive for targets that implement optimized variant.
--- kernel/trace/trace_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_clock.c +1 -1
@@ -154,5 +154,5 @@ static atomic64_t trace_counter;*/ u64 notrace trace_clock_counter(void) { -return atomic64_add_return (1 , &trace_counter); +return atomic64_inc_return (&trace_counter); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 268/356 tools/rtla: fix collision with glibc sched_attr/sched_set_attr
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Stancek <[email protected]>
[ Upstream commit 0eecee340672c4b512f6f4a8c6add26df05d130c ]
glibc commit 21571ca0d703 ("Linux: Add the sched_setattr and sched_getattr functions") now also provides 'struct sched_attr' and sched_setattr() which collide with the ones from rtla.
In file included from src/trace.c:11:
src/utils.h:49:8: error: redefinition of ‘struct sched_attr’
49 | struct sched_attr {
| ^~~~~~~~~~
In file included from /usr/include/bits/sched.h:60,
from /usr/include/sched.h:43,
from /usr/include/tracefs/tracefs.h:10,
from src/trace.c:4:
/usr/include/linux/sched/types.h:98:8: note: originally defined here
98 | struct sched_attr {
| ^~~~~~~~~~Define 'struct sched_attr' conditionally, similar to what strace did:
https://lore.kernel.org/all/[email protected]/
and rename rtla's version of sched_setattr() to avoid collision.
--- tools/tracing/rtla/src/utils.c | 4 ++-- tools/tracing/rtla/src/utils.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-)
tools/tracing/rtla/src/utils.c +2 -2
@@ -233,7 +233,7 @@ long parse_ns_duration(char *val)#define SCHED_DEADLINE 6 -static inline int sched_setattr (pid_t pid,const struct sched_attr *attr, +static inline int syscall_sched_setattr (pid_t pid,const struct sched_attr *attr,unsigned int flags) {return syscall (__NR_sched_setattr, pid, attr, flags); }
@@ -243,7 +243,7 @@ int __set_sched_attr(int pid, struct sched_attr *attr)int flags =0 ;int retval; - retval =sched_setattr (pid, attr, flags); + retval =syscall_sched_setattr (pid, attr, flags);if (retval <0 ) {err_msg ("Failed to set sched attributes to the pid %d: %s\n" , pid,strerror (errno));
tools/tracing/rtla/src/utils.h +2 -0
@@ -46,6 +46,7 @@ update_sum(unsigned long long *a, unsigned long long *b) *a += *b; } +#ifndef SCHED_ATTR_SIZE_VER0 struct sched_attr { uint32_t size; uint32_t sched_policy;
@@ -56,6 +57,7 @@ struct sched_attr {uint64_t sched_deadline; uint64_t sched_period; }; +#endif /* SCHED_ATTR_SIZE_VER0 */ int parse_prio (char *arg,struct sched_attr *sched_param);int parse_cpu_set (char *cpu_list,cpu_set_t *set);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 269/356 rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Glozar <[email protected]>
[ Upstream commit 4eba4723c5254ba8251ecb7094a5078d5c300646 ]
Most fields of struct timerlat_top_cpu are unsigned long long, but the fields {irq,thread,user}_count are int (32-bit signed).
This leads to overflow when tracing on a large number of CPUs for a long enough time:
$ rtla timerlat top -a20 -c 1-127 -d 12h ... 0 12:00:00 | IRQ Timer Latency (us) | Thread Timer Latency (us) CPU COUNT | cur min avg max | cur min avg max 1 #43200096 | 0 0 1 2 | 3 2 6 12 ... 127 #43200096 | 0 0 1 2 | 3 2 5 11 ALL #119144 e4 | 0 5 4 | 2 28 16
The average latency should be 0-1 for IRQ and 5-6 for thread, but is reported as 5 and 28, about 4 to 5 times more, due to the count overflowing when summed over all CPUs: 43200096 * 127 = 5486412192, however, 1191444898 (= 5486412192 mod MAX_INT) is reported instead, as seen on the last line of the output, and the averages are thus ~4.6 times higher than they should be (5486412192 / 1191444898 = ~4.6).
Fix the issue by changing {irq,thread,user}_count fields to unsigned long long, similarly to other fields in struct timerlat_top_cpu and to the count variable in timerlat_top_print_sum.
--- tools/tracing/rtla/src/timerlat_top.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/tracing/rtla/src/timerlat_top.c +4 -4
@@ -49,9 +49,9 @@ struct timerlat_top_params { };struct timerlat_top_cpu { -int irq_count; -int thread_count; -int user_count; +unsigned long long irq_count; +unsigned long long thread_count; +unsigned long long user_count;unsigned long long cur_irq;unsigned long long min_irq;
@@ -237,7 +237,7 @@ static void timerlat_top_print(struct osnoise_tool *top, int cpu)/* * Unless trace is being lost, IRQ counter is always the max. */ -trace_seq_printf (s,"%3d #%-9d |" , cpu, cpu_data->irq_count); +trace_seq_printf (s,"%3d #%-9llu |" , cpu, cpu_data->irq_count);if (!cpu_data->irq_count) {trace_seq_printf (s,"%s %s %s %s |" , no_value, no_value, no_value, no_value);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 270/356 scsi: hisi_sas: Add cond_resched() for no forced preemption model
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihang Li <[email protected]>
[ Upstream commit 2233c4a0b948211743659b24c13d6bd059fa75fc ]
For no forced preemption model kernel, in the scenario where the expander is connected to 12 high performance SAS SSDs, the following call trace may occur:
[ 214.409199][ C240] watchdog: BUG: soft lockup - CPU#240 stuck for 22s! [irq/149-hisi_sa:3211] [ 214.568533][ C240] pstate: 60400009 (nZCv daif +PAN -UAO -TCO BTYPE=--) [ 214.575224][ C240] pc : fput_many+0x8c/0xdc [ 214.579480][ C240] lr : fput+0x1c/0xf0 [ 214.583302][ C240] sp : ffff80002de2b900 [ 214.587298][ C240] x29: ffff80002de2b900 x28: ffff1082aa412000 [ 214.593291][ C240] x27: ffff3062a0348c08 x26: ffff80003a9f6000 [ 214.599284][ C240] x25: ffff1062bbac5c40 x24: 0000000000001000 [ 214.605277][ C240] x23: 000000000000000a x22: 0000000000000001 [ 214.611270][ C240] x21: 0000000000001000 x20: 0000000000000000 [ 214.617262][ C240] x19: ffff3062a41ae580 x18: 0000000000010000 [ 214.623255][ C240] x17: 0000000000000001 x16: ffffdb3a6efe5fc0 [ 214.629248][ C240] x15: ffffffffffffffff x14: 0000000003ffffff [ 214.635241][ C240] x13: 000000000000ffff x12: 000000000000029c [ 214.641234][ C240] x11: 0000000000000006 x10: ffff80003a9f7fd0 [ 214.647226][ C240] x9 : ffffdb3a6f0482fc x8 : 0000000000000001 [ 214.653219][ C240] x7 : 0000000000000002 x6 : 0000000000000080 [ 214.659212][ C240] x5 : ffff55480ee9b000 x4 : fffffde7f94c6554 [ 214.665205][ C240] x3 : 0000000000000002 x2 : 0000000000000020 [ 214.671198][ C240] x1 : 0000000000000021 x0 : ffff3062a41ae5b8 [ 214.677191][ C240] Call trace: [ 214.680320][ C240] fput_many+0x8c/0xdc [ 214.684230][ C240] fput+0x1c/0xf0 [ 214.687707][ C240] aio_complete_rw+0xd8/0x1fc [ 214.692225][ C240] blkdev_bio_end_io+0x98/0x140 [ 214.696917][ C240] bio_endio+0x160/0x1bc [ 214.701001][ C240] blk_update_request+0x1c8/0x3bc [ 214.705867][ C240] scsi_end_request+0x3c/0x1f0 [ 214.710471][ C240] scsi_io_completion+0x7c/0x1a0 [ 214.715249][ C240] scsi_finish_command+0x104/0x140 [ 214.720200][ C240] scsi_softirq_done+0x90/0x180 [ 214.724892][ C240] blk_mq_complete_request+0x5c/0x70 [ 214.730016][ C240] scsi_mq_done+0x48/0xac [ 214.734194][ C240] sas_scsi_task_done+0xbc/0x16c [libsas] [ 214.739758][ C240] slot_complete_v3_hw+0x260/0x760 [hisi_sas_v3_hw] [ 214.746185][ C240] cq_thread_v3_hw+0xbc/0x190 [hisi_sas_v3_hw] [ 214.752179][ C240] irq_thread_fn+0x34/0xa4 [ 214.756435][ C240] irq_thread+0xc4/0x130 [ 214.760520][ C240] kthread+0x108/0x13c [ 214.764430][ C240] ret_from_fork+0x10/0x18
This is because in the hisi_sas driver, both the hardware interrupt handler and the interrupt thread are executed on the same CPU. In the performance test scenario, function irq_wait_for_interrupt() will always return 0 if lots of interrupts occurs and the CPU will be continuously consumed. As a result, the CPU cannot run the watchdog thread. When the watchdog time exceeds the specified time, call trace occurs.
To fix it, add cond_resched() to execute the watchdog thread.
--- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +1 -0
@@ -2494,6 +2494,7 @@ static int complete_v3_hw(struct hisi_sas_cq *cq)/* update rd_point */ cq->rd_point = rd_point;hisi_sas_write32 (hisi_hba,COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); +cond_resched ();return completed; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 271/356 pinmux: Use sequential access to access desc->pinmux data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <[email protected]>
[ Upstream commit 5a3e85c3c397c781393ea5fb2f45b1f60f8a4e6e ]
When two client of the same gpio call pinctrl_select_state() for the same functionality, we are seeing NULL pointer issue while accessing desc->mux_owner.
Let's say two processes A, B executing in pin_request() for the same pin and process A updates the desc->mux_usecount but not yet updated the desc->mux_owner while process B see the desc->mux_usecount which got updated by A path and further executes strcmp and while accessing desc->mux_owner it crashes with NULL pointer.
Serialize the access to mux related setting with a mutex lock.
cpu0 (process A) cpu1(process B)
pinctrl_select_state() { pinctrl_select_state() {
pin_request() { pin_request() {
...
....
} else {
desc->mux_usecount++;
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
if (desc->mux_usecount > 1)
return 0;
desc->mux_owner = owner;} }
--- drivers/pinctrl/core.c | 3 + drivers/pinctrl/core.h | 1 + drivers/pinctrl/pinmux.c | 173 ++++++++++++++++++++++----------------- 3 files changed, 100 insertions(+), 77 deletions(-)
drivers/pinctrl/core.c +3 -0
@@ -220,6 +220,9 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,/* Set owner */ pindesc->pctldev = pctldev; +#ifdef CONFIG_PINMUX +mutex_init (&pindesc->mux_lock); +#endif /* Copy basic pin info */ if (pin->name) {
drivers/pinctrl/core.h +1 -0
@@ -177,6 +177,7 @@ struct pin_desc {const char *mux_owner;const struct pinctrl_setting_mux *mux_setting;const char *gpio_owner; +struct mutex mux_lock;#endif };
drivers/pinctrl/pinmux.c +96 -77
245 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 272/356 scsi: ufs: core: Make DMA mask configuration more flexible
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit 78bc671bd1501e2f6c571e063301a4fdc5db53b2 ]
Replace UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS with ufs_hba_variant_ops::set_dma_mask. Update the Renesas driver accordingly. This patch enables supporting other configurations than 32-bit or 64-bit DMA addresses, e.g. 36-bit DMA addresses.
--- drivers/ufs/core/ufshcd.c | 4 ++-- drivers/ufs/host/ufs-renesas.c | 9 ++++++++- include/ufs/ufshcd.h | 9 +++------ 3 files changed, 13 insertions(+), 9 deletions(-)
drivers/ufs/core/ufshcd.c +2 -2
@@ -2265,8 +2265,6 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)int err; hba->capabilities =ufshcd_readl (hba,REG_CONTROLLER_CAPABILITIES ); -if (hba->quirks &UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS ) - hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT ;/* nutrs and nutmrs are 0 based values */ hba->nutrs = (hba->capabilities &MASK_TRANSFER_REQUESTS_SLOTS ) +1 ;
@@ -10240,6 +10238,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);*/ static int ufshcd_set_dma_mask (struct ufs_hba *hba) { +if (hba->vops && hba->vops->set_dma_mask) +return hba->vops->set_dma_mask (hba);if (hba->capabilities &MASK_64_ADDRESSING_SUPPORT ) {if (!dma_set_mask_and_coherent (hba->dev,DMA_BIT_MASK (64 )))return 0 ;
drivers/ufs/host/ufs-renesas.c +8 -1
@@ -7,6 +7,7 @@#include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/err.h> #include <linux/iopoll.h> #include <linux/kernel.h>
@@ -364,14 +365,20 @@ static int ufs_renesas_init(struct ufs_hba *hba)return -ENOMEM ;ufshcd_set_variant (hba, priv); - hba->quirks |=UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS |UFSHCD_QUIRK_HIBERN_FASTAUTO ; + hba->quirks |=UFSHCD_QUIRK_HIBERN_FASTAUTO ;return 0 ; } +static int ufs_renesas_set_dma_mask (struct ufs_hba *hba) +{ +return dma_set_mask_and_coherent (hba->dev,DMA_BIT_MASK (32 )); +} +static const struct ufs_hba_variant_ops ufs_renesas_vops = { .name ="renesas" , .init = ufs_renesas_init, + .set_dma_mask = ufs_renesas_set_dma_mask, .setup_clocks = ufs_renesas_setup_clocks, .hce_enable_notify = ufs_renesas_hce_enable_notify, .dbg_register_dump = ufs_renesas_dbg_register_dump,
include/ufs/ufshcd.h +3 -6
@@ -295,6 +295,8 @@ struct ufs_pwr_mode_info {* @name: variant name * @init: called when the driver is initialized * @exit: called to cleanup everything done in init +* @set_dma_mask: For setting another DMA mask than indicated by the 64AS +* capability bit. * @get_ufs_hci_version: called to get UFS HCI version * @clk_scale_notify: notifies that clks are scaled up/down * @setup_clocks: called before touching any of the controller registers
@@ -334,6 +336,7 @@ struct ufs_hba_variant_ops {int (*init)(struct ufs_hba *);void (*exit)(struct ufs_hba *);u32 (*get_ufs_hci_version)(struct ufs_hba *); +int (*set_dma_mask)(struct ufs_hba *);int (*clk_scale_notify)(struct ufs_hba *,bool ,enum ufs_notify_change_status ); int (*setup_clocks)(struct ufs_hba *, bool,
@@ -615,12 +618,6 @@ enum ufshcd_quirks {*/ UFSHCD_QUIRK_SKIP_PH_CONFIGURATION = 1 << 16, -/* -* This quirk needs to be enabled if the host controller has -* 64-bit addressing supported capability but it doesn't work. -*/ - UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS = 1 << 17, -/* * This quirk needs to be enabled if the host controller has * auto-hibernate capability but it's FASTAUTO only.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 273/356 bpf: put bpf_links program when link is safe to be deallocated
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit f44ec8733a8469143fde1984b5e6931b2e2f6f3f ]
In general, BPF link's underlying BPF program should be considered to be reachable through attach hook -> link -> prog chain, and, pessimistically, we have to assume that as long as link's memory is not safe to free, attach hook's code might hold a pointer to BPF program and use it.
As such, it's not (generally) correct to put link's program early before waiting for RCU GPs to go through. More eager bpf_prog_put() that we currently do is mostly correct due to BPF program's release code doing similar RCU GP waiting, but as will be shown in the following patches, BPF program can be non-sleepable (and, thus, reliant on only "classic" RCU GP), while BPF link's attach hook can have sleepable semantics and needs to be protected by RCU Tasks Trace, and for such cases BPF link has to go through RCU Tasks Trace + "classic" RCU GPs before being deallocated. And so, if we put BPF program early, we might free BPF program before we free BPF link, leading to use-after-free situation.
So, this patch defers bpf_prog_put() until we are ready to perform bpf_link's deallocation. At worst, this delays BPF program freeing by one extra RCU GP, but that seems completely acceptable. Alternatively, we'd need more elaborate ways to determine BPF hook, BPF link, and BPF program lifetimes, and how they relate to each other, which seems like an unnecessary complication.
Note, for most BPF links we still will perform eager bpf_prog_put() and link dealloc, so for those BPF links there are no observable changes whatsoever. Only BPF links that use deferred dealloc might notice slightly delayed freeing of BPF programs.
Also, to reduce code and logic duplication, extract program put + link dealloc logic into bpf_link_dealloc() helper.
--- kernel/bpf/syscall.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
kernel/bpf/syscall.c +17 -5
@@ -2870,12 +2870,24 @@ void bpf_link_inc(struct bpf_link *link)atomic64_inc (&link->refcnt); } +static void bpf_link_dealloc (struct bpf_link *link) +{ +/* now that we know that bpf_link itself can't be reached, put underlying BPF program */ +if (link->prog) +bpf_prog_put (link->prog); + +/* free bpf_link and its containing memory */ +if (link->ops->dealloc_deferred) + link->ops->dealloc_deferred (link); +else + link->ops->dealloc (link); +} +static void bpf_link_defer_dealloc_rcu_gp (struct rcu_head *rcu) { struct bpf_link *link = container_of(rcu, struct bpf_link, rcu); -/* free bpf_link and its containing memory */ - link->ops->dealloc_deferred (link); +bpf_link_dealloc (link); }static void bpf_link_defer_dealloc_mult_rcu_gp (struct rcu_head *rcu)
@@ -2897,7 +2909,6 @@ static void bpf_link_free(struct bpf_link *link) sleepable = link->prog->aux->sleepable;/* detach BPF program, clean up used resources */ ops->release (link); -bpf_prog_put (link->prog); }if (ops->dealloc_deferred) {/* schedule BPF link deallocation; if underlying BPF program
@@ -2908,8 +2919,9 @@ static void bpf_link_free(struct bpf_link *link)call_rcu_tasks_trace (&link->rcu, bpf_link_defer_dealloc_mult_rcu_gp); else call_rcu(&link->rcu, bpf_link_defer_dealloc_rcu_gp); - }else if (ops->dealloc) - ops->dealloc (link); + }else if (ops->dealloc) { +bpf_link_dealloc (link); + } }static void bpf_link_put_deferred (struct work_struct *work)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 274/356 scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit d35f7672715d1ff3e3ad9bb4ae6ac6cb484200fe ]
During initialization, the driver allocates wq->pring in lpfc_wq_create and lpfc_sli4_queue_unset() is the only place where kfree(wq->pring) is called.
There is a possible memory leak in lpfc_sli_brdrestart_s4() (restart) and lpfc_pci_remove_one_s4() (rmmod) paths because there are no calls to lpfc_sli4_queue_unset() to kfree() the wq->pring.
Fix by inserting a call to lpfc_sli4_queue_unset() in lpfc_sli_brdrestart_s4() and lpfc_sli4_hba_unset() routines. Also, add a check for the SLI_ACTIVE flag before issuing the Q_DESTROY mailbox command. If not set, then the mailbox command will obviously fail. In such cases, skip issuing the mailbox command and only execute the driver resource clean up portions of the lpfc_*q_destroy routines.
--- drivers/scsi/lpfc/lpfc_init.c | 2 ++ drivers/scsi/lpfc/lpfc_sli.c | 41 ++++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-)
drivers/scsi/lpfc/lpfc_init.c +2 -0
@@ -13513,6 +13513,8 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)/* Disable FW logging to host memory */ lpfc_ras_stop_fwlog (phba); +lpfc_sli4_queue_unset (phba); +/* Reset SLI4 HBA FCoE function */ lpfc_pci_function_reset (phba);
drivers/scsi/lpfc/lpfc_sli.c +36 -5
120 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 275/356 clk: qcom: rcg2: add clk_rcg2_shared_floor_ops
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit aec8c0e28ce4a1f89fd82fcc06a5cc73147e9817 ]
Generally SDCC clocks use clk_rcg2_floor_ops, however on SAR2130P platform it's recommended to use rcg2_shared_ops for all Root Clock Generators to park them instead of disabling. Implement a mix of those, clk_rcg2_shared_floor_ops.
--- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 48 +++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-)
drivers/clk/qcom/clk-rcg.h +1 -0
@@ -176,6 +176,7 @@ extern const struct clk_ops clk_byte2_ops;extern const struct clk_ops clk_pixel_ops;extern const struct clk_ops clk_gfx3d_ops;extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_rcg2_shared_floor_ops;extern const struct clk_ops clk_rcg2_shared_no_init_park_ops;extern const struct clk_ops clk_dp_ops;
drivers/clk/qcom/clk-rcg2.c +43 -5
74 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 276/356 clk: qcom: rpmh: add support for SAR2130P
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 2cc88de6261f01ebd4e2a3b4e29681fe87d0c089 ]
Define clocks as supported by the RPMh on the SAR2130P platform. The msm-5.10 kernel declares just the CXO clock, the RF_CLK1 clock was added following recommendation from Taniya Das.
--- drivers/clk/qcom/clk-rpmh.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/clk/qcom/clk-rpmh.c +13 -0
@@ -385,6 +385,18 @@ DEFINE_CLK_RPMH_BCM(ipa, "IP0");DEFINE_CLK_RPMH_BCM (pka,"PKA0" );DEFINE_CLK_RPMH_BCM (qpic_clk,"QP0" ); +static struct clk_hw *sar2130p_rpmh_clocks[] = { + [RPMH_CXO_CLK ] = &clk_rpmh_bi_tcxo_div1.hw, + [RPMH_CXO_CLK_A ] = &clk_rpmh_bi_tcxo_div1_ao.hw, + [RPMH_RF_CLK1 ] = &clk_rpmh_rf_clk1_a.hw, + [RPMH_RF_CLK1_A ] = &clk_rpmh_rf_clk1_a_ao.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sar2130p = { + .clks = sar2130p_rpmh_clocks, + .num_clks =ARRAY_SIZE (sar2130p_rpmh_clocks), +}; +static struct clk_hw *sdm845_rpmh_clocks[] = { [RPMH_CXO_CLK ] = &clk_rpmh_bi_tcxo_div2.hw, [RPMH_CXO_CLK_A ] = &clk_rpmh_bi_tcxo_div2_ao.hw,
@@ -804,6 +816,7 @@ static int clk_rpmh_probe(struct platform_device *pdev)static const struct of_device_id clk_rpmh_match_table[] = { { .compatible ="qcom,qdu1000-rpmh-clk" , .data = &clk_rpmh_qdu1000}, { .compatible ="qcom,sa8775p-rpmh-clk" , .data = &clk_rpmh_sa8775p}, + { .compatible ="qcom,sar2130p-rpmh-clk" , .data = &clk_rpmh_sar2130p}, { .compatible ="qcom,sc7180-rpmh-clk" , .data = &clk_rpmh_sc7180}, { .compatible ="qcom,sc8180x-rpmh-clk" , .data = &clk_rpmh_sc8180x}, { .compatible ="qcom,sc8280xp-rpmh-clk" , .data = &clk_rpmh_sc8280xp},
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 277/356 clk: qcom: tcsrcc-sm8550: add SAR2130P support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit d2e0a043530b9d6f37a8de8f05e0725667aba0a6 ]
The SAR2130P platform has the same TCSR Clock Controller as the SM8550, except for the lack of the UFS clocks. Extend the SM8550 TCSRCC driver to support SAR2130P.
--- drivers/clk/qcom/tcsrcc-sm8550.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/clk/qcom/tcsrcc-sm8550.c +16 -2
@@ -129,6 +129,13 @@ static struct clk_branch tcsr_usb3_clkref_en = { }, }; +static struct clk_regmap *tcsr_cc_sar2130p_clocks[] = { + [TCSR_PCIE_0_CLKREF_EN ] = &tcsr_pcie_0_clkref_en.clkr, + [TCSR_PCIE_1_CLKREF_EN ] = &tcsr_pcie_1_clkref_en.clkr, + [TCSR_USB2_CLKREF_EN ] = &tcsr_usb2_clkref_en.clkr, + [TCSR_USB3_CLKREF_EN ] = &tcsr_usb3_clkref_en.clkr, +}; +static struct clk_regmap *tcsr_cc_sm8550_clocks[] = { [TCSR_PCIE_0_CLKREF_EN ] = &tcsr_pcie_0_clkref_en.clkr, [TCSR_PCIE_1_CLKREF_EN ] = &tcsr_pcie_1_clkref_en.clkr,
@@ -146,6 +153,12 @@ static const struct regmap_config tcsr_cc_sm8550_regmap_config = { .fast_io = true, }; +static const struct qcom_cc_desc tcsr_cc_sar2130p_desc = { + .config = &tcsr_cc_sm8550_regmap_config, + .clks = tcsr_cc_sar2130p_clocks, + .num_clks =ARRAY_SIZE (tcsr_cc_sar2130p_clocks), +}; +static const struct qcom_cc_desc tcsr_cc_sm8550_desc = { .config = &tcsr_cc_sm8550_regmap_config, .clks = tcsr_cc_sm8550_clocks,
@@ -153,7 +166,8 @@ static const struct qcom_cc_desc tcsr_cc_sm8550_desc = { };static const struct of_device_id tcsr_cc_sm8550_match_table[] = { - { .compatible ="qcom,sm8550-tcsr" }, + { .compatible ="qcom,sar2130p-tcsr" , .data = &tcsr_cc_sar2130p_desc }, + { .compatible ="qcom,sm8550-tcsr" , .data = &tcsr_cc_sm8550_desc }, { } };MODULE_DEVICE_TABLE (of, tcsr_cc_sm8550_match_table);
@@ -162,7 +176,7 @@ static int tcsr_cc_sm8550_probe(struct platform_device *pdev) {struct regmap *regmap; - regmap =qcom_cc_map (pdev, &tcsr_cc_sm8550_desc); + regmap =qcom_cc_map (pdev,of_device_get_match_data (&pdev->dev));if (IS_ERR (regmap))return PTR_ERR (regmap);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 278/356 leds: class: Protect brightness_show() with led_cdev->led_access mutex
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <[email protected]>
[ Upstream commit 4ca7cd938725a4050dcd62ae9472e931d603118d ]
There is NULL pointer issue observed if from Process A where hid device being added which results in adding a led_cdev addition and later a another call to access of led_cdev attribute from Process B can result in NULL pointer issue.
Use mutex led_cdev->led_access to protect access to led->cdev and its attribute inside brightness_show() and max_brightness_show() and also update the comment for mutex that it should be used to protect the led class device fields.
Process A Process B
kthread+0x114
worker_thread+0x244
process_scheduled_works+0x248
uhid_device_add_worker+0x24
hid_add_device+0x120
device_add+0x268
bus_probe_device+0x94
device_initial_probe+0x14
__device_attach+0xfc
bus_for_each_drv+0x10c
__device_attach_driver+0x14c
driver_probe_device+0x3c
__driver_probe_device+0xa0
really_probe+0x190
hid_device_probe+0x130
ps_probe+0x990
ps_led_register+0x94
devm_led_classdev_register_ext+0x58
led_classdev_register_ext+0x1f8
device_create_with_groups+0x48
device_create_groups_vargs+0xc8
device_add+0x244
kobject_uevent+0x14
kobject_uevent_env[jt]+0x224
mutex_unlock[jt]+0xc4
__mutex_unlock_slowpath+0xd4
wake_up_q+0x70
try_to_wake_up[jt]+0x48c
preempt_schedule_common+0x28
__schedule+0x628
__switch_to+0x174
el0t_64_sync+0x1a8/0x1ac el0t_64_sync_handler+0x68/0xbc el0_svc+0x38/0x68 do_el0_svc+0x1c/0x28 el0_svc_common+0x80/0xe0 invoke_syscall+0x58/0x114 __arm64_sys_read+0x1c/0x2c ksys_read+0x78/0xe8 vfs_read+0x1e0/0x2c8 kernfs_fop_read_iter+0x68/0x1b4 seq_read_iter+0x158/0x4ec kernfs_seq_show+0x44/0x54 sysfs_kf_seq_show+0xb4/0x130 dev_attr_show+0x38/0x74 brightness_show+0x20/0x4c dualshock4_led_get_brightness+0xc/0x74
[ 3313.874295][ T4013] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000060 [ 3313.874301][ T4013] Mem abort info: [ 3313.874303][ T4013] ESR = 0x0000000096000006 [ 3313.874305][ T4013] EC = 0x25: DABT (current EL), IL = 32 bits [ 3313.874307][ T4013] SET = 0, FnV = 0 [ 3313.874309][ T4013] EA = 0, S1PTW = 0 [ 3313.874311][ T4013] FSC = 0x06: level 2 translation fault [ 3313.874313][ T4013] Data abort info: [ 3313.874314][ T4013] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000 [ 3313.874316][ T4013] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 3313.874318][ T4013] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 3313.874320][ T4013] user pgtable: 4k pages, 39-bit VAs, pgdp=00000008f2b0a000
..
[ 3313.874332][ T4013] Dumping ftrace buffer: [ 3313.874334][ T4013] (ftrace buffer empty) .. .. [ dd3313.874639][ T4013] CPU: 6 PID: 4013 Comm: InputReader [ 3313.874648][ T4013] pc : dualshock4_led_get_brightness+0xc/0x74 [ 3313.874653][ T4013] lr : led_update_brightness+0x38/0x60 [ 3313.874656][ T4013] sp : ffffffc0b910bbd0 .. .. [ 3313.874685][ T4013] Call trace: [ 3313.874687][ T4013] dualshock4_led_get_brightness+0xc/0x74 [ 3313.874690][ T4013] brightness_show+0x20/0x4c [ 3313.874692][ T4013] dev_attr_show+0x38/0x74 [ 3313.874696][ T4013] sysfs_kf_seq_show+0xb4/0x130 [ 3313.874700][ T4013] kernfs_seq_show+0x44/0x54 [ 3313.874703][ T4013] seq_read_iter+0x158/0x4ec [ 3313.874705][ T4013] kernfs_fop_read_iter+0x68/0x1b4 [ 3313.874708][ T4013] vfs_read+0x1e0/0x2c8 [ 3313.874711][ T4013] ksys_read+0x78/0xe8 [ 3313.874714][ T4013] __arm64_sys_read+0x1c/0x2c [ 3313.874718][ T4013] invoke_syscall+0x58/0x114 [ 3313.874721][ T4013] el0_svc_common+0x80/0xe0 [ 3313.874724][ T4013] do_el0_svc+0x1c/0x28 [ 3313.874727][ T4013] el0_svc+0x38/0x68 [ 3313.874730][ T4013] el0t_64_sync_handler+0x68/0xbc [ 3313.874732][ T4013] el0t_64_sync+0x1a8/0x1ac
--- drivers/leds/led-class.c | 14 +++++++++++--- include/linux/leds.h | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-)
drivers/leds/led-class.c +11 -3
@@ -29,11 +29,14 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); +unsigned int brightness; -/* no lock needed for this */ +mutex_lock (&led_cdev->led_access);led_update_brightness (led_cdev); + brightness = led_cdev->brightness; +mutex_unlock (&led_cdev->led_access); -return sprintf (buf,"%u\n" , led_cdev->brightness); +return sprintf (buf,"%u\n" , brightness); } static ssize_t brightness_store(struct device *dev,
@@ -70,8 +73,13 @@ static ssize_t max_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); +unsigned int max_brightness; + +mutex_lock (&led_cdev->led_access); + max_brightness = led_cdev->max_brightness; +mutex_unlock (&led_cdev->led_access); -return sprintf (buf,"%u\n" , led_cdev->max_brightness); +return sprintf (buf,"%u\n" , max_brightness); }static DEVICE_ATTR_RO (max_brightness);
include/linux/leds.h +1 -1
@@ -244,7 +244,7 @@ struct led_classdev {struct kernfs_node *brightness_hw_changed_kn;#endif -/* Ensures consistent access to the LED Flash Class device */ +/* Ensures consistent access to the LED class device */ struct mutex led_access; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 279/356 scsi: st: Dont modify unknown block number in MTIOCGET
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Mäkisara <[email protected]>
[ Upstream commit 5bb2d6179d1a8039236237e1e94cfbda3be1ed9e ]
Struct mtget field mt_blkno -1 means it is unknown. Don't add anything to it.
--- drivers/scsi/st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/st.c +1 -1
@@ -3757,7 +3757,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) ((STp->density <<MT_ST_DENSITY_SHIFT ) &MT_ST_DENSITY_MASK ); mt_status.mt_blkno = STps->drv_block; mt_status.mt_fileno = STps->drv_file; -if (STp->block_size !=0 ) { +if (STp->block_size !=0 && mt_status.mt_blkno >=0 ) {if (STps->rw ==ST_WRITING ) mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 280/356 scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Mäkisara <[email protected]>
[ Upstream commit 0b120edb37dc9dd8ca82893d386922eb6b16f860 ]
Most drives rewind the tape when the device is reset. Reading and writing are not allowed until something is done to make the tape position match the user's expectation (e.g., rewind the tape). Add MTIOCGET and MTLOAD to operations allowed after reset. MTIOCGET is modified to not touch the tape if pos_unknown is non-zero. The tape location is known after MTLOAD.
--- drivers/scsi/st.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/scsi/st.c +21 -8
@@ -3507,6 +3507,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)int i, cmd_nr, cmd_type, bt;int retval =0 ;unsigned int blk; +bool cmd_mtiocget;struct scsi_tape *STp = file->private_data;struct st_modedef *STm;struct st_partstat *STps;
@@ -3620,6 +3621,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)*/ if (mtc.mt_op != MTREW && mtc.mt_op != MTOFFL && + mtc.mt_op != MTLOAD && mtc.mt_op != MTRETEN && mtc.mt_op != MTERASE && mtc.mt_op != MTSEEK &&
@@ -3733,17 +3735,28 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) goto out; } + cmd_mtiocget = cmd_type ==_IOC_TYPE (MTIOCGET ) && cmd_nr ==_IOC_NR (MTIOCGET ); +if ((i =flush_buffer (STp,0 )) <0 ) { - retval = i; - goto out; - } -if (STp->can_partitions && - (i =switch_partition (STp)) <0 ) { - retval = i; - goto out; +if (cmd_mtiocget && STp->pos_unknown) { +/* flush fails -> modify status accordingly */ +reset_state (STp); + STp->pos_unknown =1 ; + }else {/* return error */ + retval = i; + goto out; + } + }else {/* flush_buffer succeeds */ +if (STp->can_partitions) { + i =switch_partition (STp); +if (i <0 ) { + retval = i; + goto out; + } + } } -if (cmd_type ==_IOC_TYPE (MTIOCGET ) && cmd_nr ==_IOC_NR (MTIOCGET )) { +if (cmd_mtiocget) {struct mtget mt_status;if (_IOC_SIZE (cmd_in) !=sizeof (struct mtget )) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 281/356 pinctrl: qcom-pmic-gpio: add support for PM8937
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Czémán <[email protected]>
[ Upstream commit 89265a58ff24e3885c2c9ca722bc3aaa47018be9 ]
PM8937 has 8 GPIO-s with holes on GPIO3, GPIO4 and GPIO6.
--- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +2 -0
@@ -1226,6 +1226,8 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8550ve-gpio", .data = (void *) 8 }, { .compatible = "qcom,pm8550vs-gpio", .data = (void *) 6 }, { .compatible = "qcom,pm8916-gpio", .data = (void *) 4 }, + /* pm8937 has 8 GPIOs with holes on 3, 4 and 6 */ + { .compatible = "qcom,pm8937-gpio", .data = (void *) 8 }, { .compatible = "qcom,pm8941-gpio", .data = (void *) 36 }, /* pm8950 has 8 GPIOs with holes on 3 */ { .compatible = "qcom,pm8950-gpio", .data = (void *) 8 },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 282/356 pinctrl: qcom: spmi-mpp: Add PM8937 compatible
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Czémán <[email protected]>
[ Upstream commit f755261190e88f5d19fe0a3b762f0bbaff6bd438 ]
The PM8937 provides 4 MPPs.
Add a compatible to support them.
--- drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 1 + 1 file changed, 1 insertion(+)
drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +1 -0
@@ -984,6 +984,7 @@ static const struct of_device_id pmic_mpp_of_match[] = { { .compatible = "qcom,pm8226-mpp", .data = (void *) 8 }, { .compatible = "qcom,pm8841-mpp", .data = (void *) 4 }, { .compatible = "qcom,pm8916-mpp", .data = (void *) 4 }, + { .compatible = "qcom,pm8937-mpp", .data = (void *) 4 }, { .compatible = "qcom,pm8941-mpp", .data = (void *) 8 }, { .compatible = "qcom,pm8950-mpp", .data = (void *) 4 }, { .compatible = "qcom,pmi8950-mpp", .data = (void *) 4 },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 283/356 thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Czémán <[email protected]>
[ Upstream commit e2ffb6c3a40ee714160e35e61f0a984028b5d550 ]
Add support for tsens v1.4 block what can be found in MSM8937 and MSM8917.
--- drivers/thermal/qcom/tsens-v1.c | 21 ++++++++++++++------- drivers/thermal/qcom/tsens.c | 3 +++ drivers/thermal/qcom/tsens.h | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-)
drivers/thermal/qcom/tsens-v1.c +14 -7
@@ -162,28 +162,35 @@ struct tsens_plat_data data_tsens_v1 = { .fields = tsens_v1_regfields, }; -static const struct tsens_ops ops_8956 = { - .init = init_8956, +static const struct tsens_ops ops_common = { + .init = init_common, .calibrate = tsens_calibrate_common, .get_temp = get_temp_tsens_valid, }; -struct tsens_plat_data data_8956 = { +struct tsens_plat_data data_8937 = { .num_sensors =11 , - .ops = &ops_8956, + .ops = &ops_common, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, }; -static const struct tsens_ops ops_8976 = { - .init = init_common, +static const struct tsens_ops ops_8956 = { + .init = init_8956, .calibrate = tsens_calibrate_common, .get_temp = get_temp_tsens_valid, }; +struct tsens_plat_data data_8956 = { + .num_sensors =11 , + .ops = &ops_8956, + .feat = &tsens_v1_feat, + .fields = tsens_v1_regfields, +}; +struct tsens_plat_data data_8976 = { .num_sensors =11 , - .ops = &ops_8976, + .ops = &ops_common, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, };
drivers/thermal/qcom/tsens.c +3 -0
@@ -1118,6 +1118,9 @@ static const struct of_device_id tsens_table[] = { }, { .compatible = "qcom,msm8916-tsens", .data = &data_8916, + }, { + .compatible = "qcom,msm8937-tsens", + .data = &data_8937, }, { .compatible = "qcom,msm8939-tsens", .data = &data_8939,
drivers/thermal/qcom/tsens.h +1 -1
@@ -642,7 +642,7 @@ extern struct tsens_plat_data data_8960;extern struct tsens_plat_data data_8226, data_8909, data_8916, data_8939, data_8974, data_9607;/* TSENS v1 targets */ -extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956; +extern struct tsens_plat_data data_tsens_v1, data_8937, data_8976, data_8956;/* TSENS v2 targets */ extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 284/356 nvdimm: rectify the illogical code within nd_dax_probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yi Yang <[email protected]>
[ Upstream commit b61352101470f8b68c98af674e187cfaa7c43504 ]
When nd_dax is NULL, nd_pfn is consequently NULL as well. Nevertheless, it is inadvisable to perform pointer arithmetic or address-taking on a NULL pointer.
Introduce the nd_dax_devinit() function to enhance the code's logic and improve its readability.
--- drivers/nvdimm/dax_devs.c | 4 ++-- drivers/nvdimm/nd.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/nvdimm/dax_devs.c +2 -2
@@ -106,12 +106,12 @@ int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns)nvdimm_bus_lock (&ndns->dev); nd_dax =nd_dax_alloc (nd_region); - nd_pfn = &nd_dax->nd_pfn; - dax_dev =nd_pfn_devinit (nd_pfn, ndns); + dax_dev =nd_dax_devinit (nd_dax, ndns);nvdimm_bus_unlock (&ndns->dev);if (!dax_dev)return -ENOMEM ; pfn_sb =devm_kmalloc (dev,sizeof (*pfn_sb),GFP_KERNEL ); + nd_pfn = &nd_dax->nd_pfn; nd_pfn->pfn_sb = pfn_sb; rc =nd_pfn_validate (nd_pfn,DAX_SIG );dev_dbg (dev,"dax: %s\n" , rc ==0 ?dev_name (dax_dev) :"<none>" );
drivers/nvdimm/nd.h +7 -0
@@ -601,6 +601,13 @@ struct nd_dax *to_nd_dax(struct device *dev);int nd_dax_probe (struct device *dev,struct nd_namespace_common *ndns);bool is_nd_dax (const struct device *dev);struct device *nd_dax_create (struct nd_region *nd_region); +static inline struct device *nd_dax_devinit (struct nd_dax *nd_dax, +struct nd_namespace_common *ndns) +{ +if (!nd_dax) +return NULL ; +return nd_pfn_devinit (&nd_dax->nd_pfn, ndns); +}#else static inline int nd_dax_probe (struct device *dev,struct nd_namespace_common *ndns)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 285/356 smb: client: memcpy() with surrounding object base address
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit f69b0187f8745a7a9584f6b13f5e792594b88b2e ]
Like commit f1f047bd7ce0 ("smb: client: Fix -Wstringop-overflow issues"), adjust the memcpy() destination address to be based off the surrounding object rather than based off the 4-byte "Protocol" member. This avoids a build-time warning when compiling under CONFIG_FORTIFY_SOURCE with GCC 15:
In function 'fortify_memcpy_chk',
inlined from 'CIFSSMBSetPathInfo' at ../fs/smb/client/cifssmb.c:5358:2:../include/linux/fortify-string.h:571:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
571 | __write_overflow_field(p_size_field, size);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- fs/smb/client/cifssmb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/cifssmb.c +1 -1
@@ -5364,7 +5364,7 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, param_offset = offsetof(struct smb_com_transaction2_spi_req , InformationLevel) -4 ; offset = param_offset + params; - data_offset = (char *) (&pSMB->hdr.Protocol) + offset; + data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset; pSMB->ParameterOffset =cpu_to_le16 (param_offset); pSMB->DataOffset =cpu_to_le16 (offset); pSMB->SetupCount =1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 286/356 verification/dot2: Improve dot parser robustness
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriele Monaco <[email protected]>
[ Upstream commit 571f8b3f866a6d990a50fe5c89fe0ea78784d70b ]
This patch makes the dot parser used by dot2c and dot2k slightly more robust, namely:
* allows parsing files with the gv extension (GraphViz)
* correctly parses edges with any indentation
* used to work only with a single character (e.g. '\t')
Additionally it fixes a couple of warnings reported by pylint such as wrong indentation and comparison to False instead of not ...
--- tools/verification/dot2/automata.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
tools/verification/dot2/automata.py +9 -9
@@ -29,11 +29,11 @@ class Automata: def __get_model_name(self): basename = ntpath.basename(self.__dot_path) - if basename.endswith(".dot") == False: + if not basename.endswith(".dot") and not basename.endswith(".gv"): print("not a dot file") raise Exception("not a dot file: %s" % self.__dot_path) - model_name = basename[0:-4] + model_name = ntpath.splitext(basename)[0] if model_name.__len__() == 0: raise Exception("not a dot file: %s" % self.__dot_path)
@@ -68,9 +68,9 @@ class Automata: def __get_cursor_begin_events(self): cursor = 0 while self.__dot_lines[cursor].split()[0] != "{node": - cursor += 1 + cursor += 1 while self.__dot_lines[cursor].split()[0] == "{node": - cursor += 1 + cursor += 1 # skip initial state transition cursor += 1 return cursor
@@ -94,11 +94,11 @@ class Automata: initial_state = state[7:] else: states.append(state) - if self.__dot_lines[cursor].__contains__("doublecircle") == True: + if "doublecircle" in self.__dot_lines[cursor]: final_states.append(state) has_final_states = True - if self.__dot_lines[cursor].__contains__("ellipse") == True: + if "ellipse" in self.__dot_lines[cursor]: final_states.append(state) has_final_states = True
@@ -110,7 +110,7 @@ class Automata: # Insert the initial state at the bein og the states states.insert(0, initial_state) - if has_final_states == False: + if not has_final_states: final_states.append(initial_state) return states, initial_state, final_states
@@ -120,7 +120,7 @@ class Automata: cursor = self.__get_cursor_begin_events() events = [] - while self.__dot_lines[cursor][1] == '"': + while self.__dot_lines[cursor].lstrip()[0] == '"': # transitions have the format: # "all_fired" -> "both_fired" [ label = "disable_irq" ]; # ------------ event is here ------------^^^^^
@@ -161,7 +161,7 @@ class Automata: # and we are back! Let's fill the matrix cursor = self.__get_cursor_begin_events() - while self.__dot_lines[cursor][1] == '"': + while self.__dot_lines[cursor].lstrip()[0] == '"': if self.__dot_lines[cursor].split()[1] == "->": line = self.__dot_lines[cursor].split() origin_state = line[0].replace('"','').replace(',','_')
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 287/356 f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Han <[email protected]>
[ Upstream commit d5c367ef8287fb4d235c46a2f8c8d68715f3a0ca ]
creating a large files during checkpoint disable until it runs out of space and then delete it, then remount to enable checkpoint again, and then unmount the filesystem triggers the f2fs_bug_on as below:
------------[ cut here ]------------ kernel BUG at fs/f2fs/inode.c:896! CPU: 2 UID: 0 PID: 1286 Comm: umount Not tainted 6.11.0-rc7-dirty #360 Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI RIP: 0010:f2fs_evict_inode+0x58c/0x610 Call Trace: __die_body+0x15/0x60 die+0x33/0x50 do_trap+0x10a/0x120 f2fs_evict_inode+0x58c/0x610 do_error_trap+0x60/0x80 f2fs_evict_inode+0x58c/0x610 exc_invalid_op+0x53/0x60 f2fs_evict_inode+0x58c/0x610 asm_exc_invalid_op+0x16/0x20 f2fs_evict_inode+0x58c/0x610 evict+0x101/0x260 dispose_list+0x30/0x50 evict_inodes+0x140/0x190 generic_shutdown_super+0x2f/0x150 kill_block_super+0x11/0x40 kill_f2fs_super+0x7d/0x140 deactivate_locked_super+0x2a/0x70 cleanup_mnt+0xb3/0x140 task_work_run+0x61/0x90
The root cause is: creating large files during disable checkpoint period results in not enough free segments, so when writing back root inode will failed in f2fs_enable_checkpoint. When umount the file system after enabling checkpoint, the root inode is dirty in f2fs_evict_inode function, which triggers BUG_ON. The steps to reproduce are as follows:
dd if=/dev/zero of=f2fs.img bs=1M count=55
mount f2fs.img f2fs_dir -o checkpoint=disable:10%
dd if=/dev/zero of=big bs=1M count=50
sync
rm big
mount -o remount,checkpoint=enable f2fs_dir
umount f2fs_dir
Let's redirty inode when there is not free segments during checkpoint is disable.
--- fs/f2fs/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/f2fs/inode.c +3 -1
@@ -788,8 +788,10 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) !is_inode_flag_set(inode, FI_DIRTY_INODE))return 0 ; -if (!f2fs_is_checkpoint_ready (sbi)) +if (!f2fs_is_checkpoint_ready (sbi)) { +f2fs_mark_inode_dirty_sync (inode, true);return -ENOSPC ; + }/* * We need to balance fs here to prevent from producing dirty node pages
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 288/356 KMSAN: uninit-value in inode_go_dump (5)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qianqiang Liu <[email protected]>
[ Upstream commit f9417fcfca3c5e30a0b961e7250fab92cfa5d123 ]
When mounting of a corrupted disk image fails, the error message printed can reference uninitialized inode fields. To prevent that from happening, always initialize those fields.
--- fs/gfs2/super.c | 2 ++ 1 file changed, 2 insertions(+)
fs/gfs2/super.c +2 -0
@@ -1567,11 +1567,13 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)if (!ip)return NULL ; ip->i_no_addr =0 ; + ip->i_no_formal_ino =0 ; ip->i_flags =0 ; ip->i_gl =NULL ;gfs2_holder_mark_uninitialized (&ip->i_iopen_gh);memset (&ip->i_res,0 ,sizeof (ip->i_res));RB_CLEAR_NODE (&ip->i_res.rs_node); + ip->i_diskflags =0 ; ip->i_rahead =0 ;return &ip->i_inode; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 289/356 i3c: mipi-i3c-hci: Mask ring interrupts before ring stop request
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Nikula <[email protected]>
[ Upstream commit 6ca2738174e4ee44edb2ab2d86ce74f015a0cc32 ]
Bus cleanup path in DMA mode may trigger a RING_OP_STAT interrupt when the ring is being stopped. Depending on timing between ring stop request completion, interrupt handler removal and code execution this may lead to a NULL pointer dereference in hci_dma_irq_handler() if it gets to run after the io_data pointer is set to NULL in hci_dma_cleanup().
Prevent this my masking the ring interrupts before ring stop request.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i3c/master/mipi-i3c-hci/dma.c +1 -1
@@ -174,10 +174,10 @@ static void hci_dma_cleanup(struct i3c_hci *hci)for (i =0 ; i < rings->total; i++) { rh = &rings->headers[i]; +rh_reg_write (INTR_SIGNAL_ENABLE ,0 );rh_reg_write (RING_CONTROL ,0 );rh_reg_write (CR_SETUP ,0 );rh_reg_write (IBI_SETUP ,0 ); -rh_reg_write (INTR_SIGNAL_ENABLE ,0 );if (rh->xfer) dma_free_coherent(&hci->master.dev,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 290/356 PCI: qcom: Add support for IPQ9574
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: devi priya <[email protected]>
[ Upstream commit a63b74f2e35be3829f256922037ae5cee6bb844a ]
Add the new IPQ9574 platform which is based on the Qcom IP rev. 1.27.0 and Synopsys IP rev. 5.80a.
The platform itself has four PCIe Gen3 controllers: two single-lane and two dual-lane, all are based on Synopsys IP rev. 5.70a. As such, reuse all the members of 'ops_2_9_0'.
--- drivers/pci/controller/dwc/pcie-qcom.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/controller/dwc/pcie-qcom.c +1 -0
@@ -1618,6 +1618,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 }, { .compatible = "qcom,pcie-ipq8074", .data = &cfg_2_3_3 }, { .compatible = "qcom,pcie-ipq8074-gen3", .data = &cfg_2_9_0 }, + { .compatible = "qcom,pcie-ipq9574", .data = &cfg_2_9_0 }, { .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 }, { .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 }, { .compatible = "qcom,pcie-sa8540p", .data = &cfg_1_9_0 },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 291/356 PCI: vmd: Add DID 8086:B06F and 8086:B60B for Intel client SKUs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nirmal Patel <[email protected]>
[ Upstream commit b727484cace4be22be9321cc0bc9487648ba447b ]
Add support for this VMD device which supports the bus restriction mode. The feature that turns off vector 0 for MSI-X remapping is also enabled.
--- drivers/pci/controller/vmd.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/pci/controller/vmd.c +4 -0
@@ -1114,6 +1114,10 @@ static const struct pci_device_id vmd_ids[] = { .driver_data = VMD_FEATS_CLIENT,}, {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, 0xb60b), + .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, 0xb06f), + .driver_data = VMD_FEATS_CLIENT,}, {0,} };MODULE_DEVICE_TABLE (pci, vmd_ids);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 292/356 PCI: vmd: Set devices to D0 before enabling PM L1 Substates
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian-Hong Pan <[email protected]>
[ Upstream commit d66041063192497a4a97d21dbf86b79a03a7f4fb ]
The remapped PCIe Root Port and the child device have PM L1 Substates capability, but they are disabled originally.
Here is a failed example on ASUS B1400CEAE:
Capabilities: [900 v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1- ASPM_L1.2+ ASPM_L1.1- L1_PM_Substates+
PortCommonModeRestoreTime=32us PortTPowerOnTime=10us
L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2+ ASPM_L1.1-
T_CommonMode=0us LTR1.2_Threshold=101376ns
L1SubCtl2: T_PwrOn=50usEnable PCI-PM L1 PM Substates for devices below VMD while they are in D0 (see PCIe r6.0, sec 5.5.4).
--- drivers/pci/controller/vmd.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/pci/controller/vmd.c +9 -4
@@ -751,11 +751,9 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)if (!(features &VMD_FEAT_BIOS_PM_QUIRK ))return 0 ; -pci_enable_link_state_locked (pdev,PCIE_LINK_STATE_ALL ); - pos =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_LTR );if (!pos) -return 0 ; + goto out_state_change;/* * Skip if the max snoop LTR is non-zero, indicating BIOS has set it
@@ -763,7 +761,7 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)*/ pci_read_config_dword (pdev, pos +PCI_LTR_MAX_SNOOP_LAT , <r_reg);if (!!(ltr_reg & (PCI_LTR_VALUE_MASK |PCI_LTR_SCALE_MASK ))) -return 0 ; + goto out_state_change;/* * Set the default values to the maximum required by the platform to
@@ -775,6 +773,13 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)pci_write_config_dword (pdev, pos +PCI_LTR_MAX_SNOOP_LAT , ltr_reg);pci_info (pdev,"VMD: Default LTR value set by driver\n" ); +out_state_change: +/* +* Ensure devices are in D0 before enabling PCI-PM L1 PM Substates, per +* PCIe r6.0, sec 5.5.4. +*/ +pci_set_power_state_locked (pdev,PCI_D0 ); +pci_enable_link_state_locked (pdev,PCIE_LINK_STATE_ALL );return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 293/356 PCI: Detect and trust built-in Thunderbolt chips
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esther Shimanovich <[email protected]>
[ Upstream commit 3b96b895127b7c0aed63d82c974b46340e8466c1 ]
Some computers with CPUs that lack Thunderbolt features use discrete Thunderbolt chips to add Thunderbolt functionality. These Thunderbolt chips are located within the chassis; between the Root Port labeled ExternalFacingPort and the USB-C port.
These Thunderbolt PCIe devices should be labeled as fixed and trusted, as they are built into the computer. Otherwise, security policies that rely on those flags may have unintended results, such as preventing USB-C ports from enumerating.
Detect the above scenario through the process of elimination.
1) Integrated Thunderbolt host controllers already have Thunderbolt implemented, so anything outside their external facing Root Port is removable and untrusted.
Detect them using the following properties:
- Most integrated host controllers have the "usb4-host-interface" ACPI property, as described here:
- Integrated Thunderbolt PCIe Root Ports before Alder Lake do not have the "usb4-host-interface" ACPI property. Identify those by their PCI IDs instead.
2) If a Root Port does not have integrated Thunderbolt capabilities, but has the "ExternalFacingPort" ACPI property, that means the manufacturer has opted to use a discrete Thunderbolt host controller that is built into the computer.
This host controller can be identified by virtue of being located directly below an external-facing Root Port that lacks integrated Thunderbolt. Label it as trusted and fixed.
Everything downstream from it is untrusted and removable.
The "ExternalFacingPort" ACPI property is described here:
https://learn.microsoft.com/en-us/windows-hardware/drivers/pci/dsd-for-pcie-root-ports#identifying-externally-exposed-pcie-root-ports
--- arch/x86/pci/acpi.c | 119 ++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/probe.c | 30 ++++++++--- include/linux/pci.h | 6 +++ 3 files changed, 148 insertions(+), 7 deletions(-)
arch/x86/pci/acpi.c +119 -0
@@ -250,6 +250,125 @@ void __init pci_acpi_crs_quirks(void)pr_info ("Please notify [email protected] so future kernels can do this automatically\n" ); } +/* +* Check if pdev is part of a PCIe switch that is directly below the +* specified bridge. +*/ +static bool pcie_switch_directly_under (struct pci_dev *bridge, +struct pci_dev *pdev) +{ +struct pci_dev *parent =pci_upstream_bridge (pdev); + +/* If the device doesn't have a parent, it's not under anything */ +if (!parent) +return false; + +/* +* If the device has a PCIe type, check if it is below the +* corresponding PCIe switch components (if applicable). Then check +* if its upstream port is directly beneath the specified bridge. +*/ +switch (pci_pcie_type (pdev)) { +case PCI_EXP_TYPE_UPSTREAM : +return parent == bridge; + +case PCI_EXP_TYPE_DOWNSTREAM : +if (pci_pcie_type (parent) !=PCI_EXP_TYPE_UPSTREAM ) +return false; + parent =pci_upstream_bridge (parent); +return parent == bridge; + +case PCI_EXP_TYPE_ENDPOINT : +if (pci_pcie_type (parent) !=PCI_EXP_TYPE_DOWNSTREAM ) +return false; + parent =pci_upstream_bridge (parent); +if (!parent ||pci_pcie_type (parent) !=PCI_EXP_TYPE_UPSTREAM ) +return false; + parent =pci_upstream_bridge (parent); +return parent == bridge; + } + +return false; +} + +static bool pcie_has_usb4_host_interface (struct pci_dev *pdev) +{ +struct fwnode_handle *fwnode; + +/* +* For USB4, the tunneled PCIe Root or Downstream Ports are marked +* with the "usb4-host-interface" ACPI property, so we look for +* that first. This should cover most cases. +*/ + fwnode =fwnode_find_reference (dev_fwnode (&pdev->dev), +"usb4-host-interface" ,0 ); +if (!IS_ERR (fwnode)) { +fwnode_handle_put (fwnode); +return true; + } + +/* +* Any integrated Thunderbolt 3/4 PCIe Root Ports from Intel +* before Alder Lake do not have the "usb4-host-interface" +* property so we use their PCI IDs instead. All these are +* tunneled. This list is not expected to grow. +*/ +if (pdev->vendor ==PCI_VENDOR_ID_INTEL ) { +switch (pdev->device) { +/* Ice Lake Thunderbolt 3 PCIe Root Ports */ +case 0x8a1d : +case 0x8a1f : +case 0x8a21 : +case 0x8a23 : +/* Tiger Lake-LP Thunderbolt 4 PCIe Root Ports */ +case 0x9a23 : +case 0x9a25 : +case 0x9a27 : +case 0x9a29 : +/* Tiger Lake-H Thunderbolt 4 PCIe Root Ports */ +case 0x9a2b : +case 0x9a2d : +case 0x9a2f : +case 0x9a31 : +return true; + } + } + +return false; +} + +bool arch_pci_dev_is_removable (struct pci_dev *pdev) +{ +struct pci_dev *parent, *root; + +/* pdev without a parent or Root Port is never tunneled */ + parent =pci_upstream_bridge (pdev); +if (!parent) +return false; + root =pcie_find_root_port (pdev); +if (!root) +return false; + +/* Internal PCIe devices are not tunneled */ +if (!root->external_facing) +return false; + +/* Anything directly behind a "usb4-host-interface" is tunneled */ +if (pcie_has_usb4_host_interface (parent)) +return true; + +/* +* Check if this is a discrete Thunderbolt/USB4 controller that is +* directly behind the non-USB4 PCIe Root Port marked as +* "ExternalFacingPort". Those are not behind a PCIe tunnel. +*/ +if (pcie_switch_directly_under (root, pdev)) +return false; + +/* PCIe devices after the discrete chip are tunneled */ +return true; +} +#ifdef CONFIG_PCI_MMCONFIG static int check_segment (u16 seg,struct device *dev,char *estr) {
drivers/pci/probe.c +23 -7
@@ -1602,23 +1602,33 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)static void set_pcie_untrusted (struct pci_dev *dev) { -struct pci_dev *parent; +struct pci_dev *parent =pci_upstream_bridge (dev); +if (!parent) +return ;/* -* If the upstream bridge is untrusted we treat this device +* If the upstream bridge is untrusted we treat this device as * untrusted as well. */ - parent =pci_upstream_bridge (dev); -if (parent && (parent->untrusted || parent->external_facing)) +if (parent->untrusted) { + dev->untrusted = true; +return ; + } + +if (arch_pci_dev_is_removable (dev)) { +pci_dbg (dev,"marking as untrusted\n" ); dev->untrusted = true; + } }static void pci_set_removable (struct pci_dev *dev) {struct pci_dev *parent =pci_upstream_bridge (dev); +if (!parent) +return ;/* -* We (only) consider everything downstream from an external_facing +* We (only) consider everything tunneled below an external_facing * device to be removable by the user. We're mainly concerned with * consumer platforms with user accessible thunderbolt ports that are * vulnerable to DMA attacks, and we expect those ports to be marked by
@@ -1628,9 +1638,15 @@ static void pci_set_removable(struct pci_dev *dev)* accessible to user / may not be removed by end user, and thus not * exposed as "removable" to userspace. */ -if (parent && - (parent->external_facing ||dev_is_removable (&parent->dev))) +if (dev_is_removable (&parent->dev)) { +dev_set_removable (&dev->dev,DEVICE_REMOVABLE ); +return ; + } + +if (arch_pci_dev_is_removable (dev)) { +pci_dbg (dev,"marking as removable\n" );dev_set_removable (&dev->dev,DEVICE_REMOVABLE ); + } }/**
include/linux/pci.h +6 -0
@@ -2577,6 +2577,12 @@ pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }static inline bool pci_pr3_present (struct pci_dev *pdev) {return false; }#endif +#if defined(CONFIG_X86 ) && defined(CONFIG_ACPI ) +bool arch_pci_dev_is_removable (struct pci_dev *pdev); +#else +static inline bool arch_pci_dev_is_removable (struct pci_dev *pdev) {return false; } +#endif +#ifdef CONFIG_EEH static inline struct eeh_dev *pci_dev_to_eeh_dev (struct pci_dev *pdev) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 294/356 PCI: Add reset_subordinate to reset hierarchy below bridge
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <[email protected]>
[ Upstream commit 2fa046449a82a7d0f6d9721dd83e348816038444 ]
The "bus" and "cxl_bus" reset methods reset a device by asserting Secondary Bus Reset on the bridge leading to the device. These only work if the device is the only device below the bridge.
Add a sysfs 'reset_subordinate' attribute on bridges that can assert Secondary Bus Reset regardless of how many devices are below the bridge.
This resets all the devices below a bridge in a single command, including the locking and config space save/restore that reset methods normally do.
This may be the only way to reset devices that don't support other reset methods (ACPI, FLR, PM reset, etc).
--- Documentation/ABI/testing/sysfs-bus-pci | 11 +++++++++++ drivers/pci/pci-sysfs.c | 26 +++++++++++++++++++++++++ drivers/pci/pci.c | 2 +- drivers/pci/pci.h | 1 + 4 files changed, 39 insertions(+), 1 deletion(-)
Documentation/ABI/testing/sysfs-bus-pci +11 -0
@@ -163,6 +163,17 @@ Description: will be present in sysfs. Writing 1 to this file will perform reset. +What: /sys/bus/pci/devices/.../reset_subordinate +Date: October 2024 +Contact: [email protected] +Description: + This is visible only for bridge devices. If you want to reset + all devices attached through the subordinate bus of a specific + bridge device, writing 1 to this will try to do it. This will + affect all devices attached to the system through this bridge + similiar to writing 1 to their individual "reset" file, so use + with caution. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>
drivers/pci/pci-sysfs.c +26 -0
@@ -517,6 +517,31 @@ static ssize_t bus_rescan_store(struct device *dev,static struct device_attribute dev_attr_bus_rescan =__ATTR (rescan,0200 ,NULL , bus_rescan_store); +static ssize_t reset_subordinate_store (struct device *dev, +struct device_attribute *attr, +const char *buf,size_t count) +{ +struct pci_dev *pdev =to_pci_dev (dev); +struct pci_bus *bus = pdev->subordinate; +unsigned long val; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (kstrtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (val) { +int ret =__pci_reset_bus (bus); + +if (ret) +return ret; + } + +return count; +} +static DEVICE_ATTR_WO (reset_subordinate); +#if defined(CONFIG_PM ) && defined(CONFIG_ACPI ) static ssize_t d3cold_allowed_store(struct device *dev, struct device_attribute *attr,
@@ -621,6 +646,7 @@ static struct attribute *pci_dev_attrs[] = {static struct attribute *pci_bridge_attrs[] = { &dev_attr_subordinate_bus_number.attr, &dev_attr_secondary_bus_number.attr, + &dev_attr_reset_subordinate.attr,NULL , };
drivers/pci/pci.c +1 -1
@@ -6069,7 +6069,7 @@ EXPORT_SYMBOL_GPL(pci_probe_reset_bus);* * Same as above except return -EAGAIN if the bus cannot be locked */ -static int __pci_reset_bus (struct pci_bus *bus) +int __pci_reset_bus (struct pci_bus *bus) {int rc;
drivers/pci/pci.h +1 -0
@@ -49,6 +49,7 @@ bool pci_reset_supported(struct pci_dev *dev);void pci_init_reset_methods (struct pci_dev *dev);int pci_bridge_secondary_bus_reset (struct pci_dev *dev);int pci_bus_error_reset (struct pci_dev *dev); +int __pci_reset_bus (struct pci_bus *bus);struct pci_cap_saved_data {u16 cap_nr;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 295/356 PCI: Add ACS quirk for Wangxun FF5xxx NICs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mengyuan Lou <[email protected]>
[ Upstream commit aa46a3736afcb7b0793766d22479b8b99fc1b322 ]
Wangxun FF5xxx NICs are similar to SFxxx, RP1000 and RP2000 NICs. They may be multi-function devices, but they do not advertise an ACS capability.
But the hardware does isolate FF5xxx functions as though it had an ACS capability and PCI_ACS_RR and PCI_ACS_CR were set in the ACS Control register, i.e., all peer-to-peer traffic is directed upstream instead of being routed internally.
Add ACS quirk for FF5xxx NICs in pci_quirk_wangxun_nic_acs() so the functions can be in independent IOMMU groups.
--- drivers/pci/quirks.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/pci/quirks.c +9 -6
@@ -4989,18 +4989,21 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags) }/* -* Wangxun 10G/1G NICs have no ACS capability, and on multi-function -* devices, peer-to-peer transactions are not be used between the functions. -* So add an ACS quirk for below devices to isolate functions. +* Wangxun 40G/25G/10G/1G NICs have no ACS capability, but on +* multi-function devices, the hardware isolates the functions by +* directing all peer-to-peer traffic upstream as though PCI_ACS_RR and +* PCI_ACS_CR were set. * SFxxx 1G NICs(em). * RP1000/RP2000 10G NICs(sp). +* FF5xxx 40G/25G/10G NICs(aml). */ static int pci_quirk_wangxun_nic_acs (struct pci_dev *dev,u16 acs_flags) {switch (dev->device) { - case 0x0100 ... 0x010F: -case 0x1001 : -case 0x2001 : + case 0x0100 ... 0x010F: /* EM */ +case 0x1001 :case 0x2001 :/* SP */ +case 0x5010 :case 0x5025 :case 0x5040 :/* AML */ +case 0x5110 :case 0x5125 :case 0x5140 :/* AML */ return pci_acs_ctrl_enabled (acs_flags,PCI_ACS_SV |PCI_ACS_RR |PCI_ACS_CR |PCI_ACS_UF ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 296/356 i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Defa Li <[email protected]>
[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]
A deadlock may happen since the i3c_master_register() acquires &i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to avoid acquiring the lock twice.
v2:
- Modified the title and commit message
============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock
but task is already holding lock:f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(&i3cbus->lock);
lock(&i3cbus->lock);
*** DEADLOCK ***
May be due to missing lock nesting notation
2 locks held by init/1:
#0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register
stack backtrace: CPU: 6 UID: 0 PID: 1 Comm: init Call trace: dump_backtrace+0xfc/0x17c show_stack+0x18/0x28 dump_stack_lvl+0x40/0xc0 dump_stack+0x18/0x24 print_deadlock_bug+0x388/0x390 __lock_acquire+0x18bc/0x32ec lock_acquire+0x134/0x2b0 down_read+0x50/0x19c i3c_bus_normaluse_lock+0x14/0x24 i3c_device_get_info+0x24/0x58 i3c_device_uevent+0x34/0xa4 dev_uevent+0x310/0x384 kobject_uevent_env+0x244/0x414 kobject_uevent+0x14/0x20 device_add+0x278/0x460 device_register+0x20/0x34 i3c_master_register_new_i3c_devs+0x78/0x154 i3c_master_register+0x6a0/0x6d4 mtk_i3c_master_probe+0x3b8/0x4d8 platform_probe+0xa0/0xe0 really_probe+0x114/0x454 __driver_probe_device+0xa0/0x15c driver_probe_device+0x3c/0x1ac __driver_attach+0xc4/0x1f0 bus_for_each_dev+0x104/0x160 driver_attach+0x24/0x34 bus_add_driver+0x14c/0x294 driver_register+0x68/0x104 __platform_driver_register+0x20/0x30 init_module+0x20/0xfe4 do_one_initcall+0x184/0x464 do_init_module+0x58/0x1ec load_module+0xefc/0x10c8 __arm64_sys_finit_module+0x238/0x33c invoke_syscall+0x58/0x10c el0_svc_common+0xa8/0xdc do_el0_svc+0x1c/0x28 el0_svc+0x50/0xac el0t_64_sync_handler+0x70/0xbc el0t_64_sync+0x1a8/0x1ac
--- drivers/i3c/master.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/i3c/master.c +2 -1
@@ -280,7 +280,8 @@ static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *estruct i3c_device_info devinfo;u16 manuf, part, ext; -i3c_device_get_info (i3cdev, &devinfo); +if (i3cdev->desc) + devinfo = i3cdev->desc->info; manuf =I3C_PID_MANUF_ID (devinfo.pid); part =I3C_PID_PART_ID (devinfo.pid); ext =I3C_PID_EXTRA_INFO (devinfo.pid);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 297/356 f2fs: print message if fscorrupted was found in f2fs_new_node_page()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 81520c684ca67aea6a589461a3caebb9b11dcc90 ]
If fs corruption occurs in f2fs_new_node_page(), let's print more information about corrupted metadata into kernel log.
Meanwhile, it updates to record ERROR_INCONSISTENT_NAT instead of ERROR_INVALID_BLKADDR if blkaddr in nat entry is not NULL_ADDR which means nat bitmap and nat entry is inconsistent.
--- fs/f2fs/node.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/f2fs/node.c +6 -1
@@ -1331,7 +1331,12 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs) err = -EFSCORRUPTED ;dec_valid_node_count (sbi, dn->inode, !ofs);set_sbi_flag (sbi,SBI_NEED_FSCK ); -f2fs_handle_error (sbi,ERROR_INVALID_BLKADDR ); +f2fs_warn_ratelimited (sbi, +"f2fs_new_node_page: inconsistent nat entry, " +"ino:%u, nid:%u, blkaddr:%u, ver:%u, flag:%u" , + new_ni.ino, new_ni.nid, new_ni.blk_addr, + new_ni.version, new_ni.flag); +f2fs_handle_error (sbi,ERROR_INCONSISTENT_NAT ); goto fail; }#endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 298/356 f2fs: fix to shrink read extent node in batches
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 3fc5d5a182f6a1f8bd4dc775feb54c369dd2c343 ]
We use rwlock to protect core structure data of extent tree during its shrink, however, if there is a huge number of extent nodes in extent tree, during shrink of extent tree, it may hold rwlock for a very long time, which may trigger kernel hang issue.
This patch fixes to shrink read extent node in batches, so that, critical region of the rwlock can be shrunk to avoid its extreme long time hold.
--- fs/f2fs/extent_cache.c | 69 +++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 28 deletions(-)
fs/f2fs/extent_cache.c +41 -28
@@ -347,21 +347,22 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode, }static unsigned int __free_extent_tree (struct f2fs_sb_info *sbi, -struct extent_tree *et) +struct extent_tree *et,unsigned int nr_shrink) {struct rb_node *node, *next;struct extent_node *en; -unsigned int count =atomic_read (&et->node_cnt); +unsigned int count; node =rb_first_cached (&et->root); -while (node) { + +for (count =0 ; node && count < nr_shrink; count++) { next =rb_next (node); en = rb_entry(node, struct extent_node, rb_node);__release_extent_node (sbi, et, en); node = next; } -return count -atomic_read (&et->node_cnt); +return count; } static void __drop_largest_extent(struct extent_tree *et,
@@ -580,6 +581,30 @@ static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,return en; } +static unsigned int __destroy_extent_node (struct inode *inode, +enum extent_type type) +{ +struct f2fs_sb_info *sbi =F2FS_I_SB (inode); +struct extent_tree *et =F2FS_I (inode)->extent_tree[type]; +unsigned int nr_shrink = type ==EX_READ ? +READ_EXTENT_CACHE_SHRINK_NUMBER : +AGE_EXTENT_CACHE_SHRINK_NUMBER ; +unsigned int node_cnt =0 ; + +if (!et || !atomic_read (&et->node_cnt)) +return 0 ; + +while (atomic_read (&et->node_cnt)) { +write_lock (&et->lock); + node_cnt +=__free_extent_tree (sbi, et, nr_shrink); +write_unlock (&et->lock); + } + +f2fs_bug_on (sbi,atomic_read (&et->node_cnt)); + +return node_cnt; +} +static void __update_extent_tree_range (struct inode *inode,struct extent_info *tei,enum extent_type type) {
@@ -718,9 +743,6 @@ static void __update_extent_tree_range(struct inode *inode, } } -if (is_inode_flag_set (inode,FI_NO_EXTENT )) -__free_extent_tree (sbi, et); -if (et->largest_updated) { et->largest_updated = false; updated = true;
@@ -738,6 +760,9 @@ static void __update_extent_tree_range(struct inode *inode, out_read_extent_cache:write_unlock (&et->lock); +if (is_inode_flag_set (inode,FI_NO_EXTENT )) +__destroy_extent_node (inode,EX_READ ); +if (updated)f2fs_mark_inode_dirty_sync (inode, true); }
@@ -902,10 +927,14 @@ static unsigned int __shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrinklist_for_each_entry_safe (et, next, &eti->zombie_list, list) {if (atomic_read (&et->node_cnt)) {write_lock (&et->lock); - node_cnt +=__free_extent_tree (sbi, et); + node_cnt +=__free_extent_tree (sbi, et, + nr_shrink - node_cnt - tree_cnt);write_unlock (&et->lock); } -f2fs_bug_on (sbi,atomic_read (&et->node_cnt)); + +if (atomic_read (&et->node_cnt)) + goto unlock_out; +list_del_init (&et->list);radix_tree_delete (&eti->extent_tree_root, et->ino);kmem_cache_free (extent_tree_slab, et);
@@ -1044,23 +1073,6 @@ unsigned int f2fs_shrink_age_extent_tree(struct f2fs_sb_info *sbi, int nr_shrinkreturn __shrink_extent_tree (sbi, nr_shrink,EX_BLOCK_AGE ); } -static unsigned int __destroy_extent_node (struct inode *inode, -enum extent_type type) -{ -struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -struct extent_tree *et =F2FS_I (inode)->extent_tree[type]; -unsigned int node_cnt =0 ; - -if (!et || !atomic_read (&et->node_cnt)) -return 0 ; - -write_lock (&et->lock); - node_cnt =__free_extent_tree (sbi, et); -write_unlock (&et->lock); - -return node_cnt; -} -void f2fs_destroy_extent_node (struct inode *inode) {__destroy_extent_node (inode,EX_READ );
@@ -1069,7 +1081,6 @@ void f2fs_destroy_extent_node(struct inode *inode)static void __drop_extent_tree (struct inode *inode,enum extent_type type) { -struct f2fs_sb_info *sbi =F2FS_I_SB (inode);struct extent_tree *et =F2FS_I (inode)->extent_tree[type];bool updated = false;
@@ -1077,7 +1088,6 @@ static void __drop_extent_tree(struct inode *inode, enum extent_type type)return ;write_lock (&et->lock); -__free_extent_tree (sbi, et);if (type ==EX_READ ) {set_inode_flag (inode,FI_NO_EXTENT );if (et->largest.len) {
@@ -1086,6 +1096,9 @@ static void __drop_extent_tree(struct inode *inode, enum extent_type type) } }write_unlock (&et->lock); + +__destroy_extent_node (inode, type); +if (updated)f2fs_mark_inode_dirty_sync (inode, true); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 299/356 ACPI: x86: Add skip i2c clients quirk for Acer Iconia One 8 A1-840
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
[ Upstream commit 82f250ed1a1dcde0ad2a1513f85af7f9514635e8 ]
The Acer Iconia One 8 A1-840 (not to be confused with the A1-840FHD which is a different model) ships with Android 4.4 as factory OS and has the usual broken DSDT issues for x86 Android tablets.
Add quirks to skip ACPI I2C client enumeration and disable ACPI battery/AC and ACPI GPIO event handlers.
Also add the "INT33F5" HID for the TI PMIC used on this tablet to the list of HIDs for which not to skip i2c_client instantiation, since we do want an ACPI instantiated i2c_client for the PMIC.
--- drivers/acpi/x86/utils.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/acpi/x86/utils.c +13 -0
@@ -300,6 +300,18 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY | ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS), }, + { +/* Acer Iconia One 8 A1-840 (non FHD version) */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Insyde" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"BayTrail" ), +/* Above strings are too generic also match BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), + }, + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | +ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY | + ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS), + }, { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
@@ -418,6 +430,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = { { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ { "10EC5651", 0 }, /* RealTek ALC5651 audio codec */ { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ + { "INT33F5", 0 }, /* TI Dollar Cove PMIC */ { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */ { "INT34D3", 0 }, /* Intel Whiskey Cove PMIC */ { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 300/356 ACPI: x86: Clean up Asus entries in acpi_quirk_skip_dmi_ids[]
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
[ Upstream commit bd8aa15848f5f21951cd0b0d01510b3ad1f777d4 ]
The Asus entries in the acpi_quirk_skip_dmi_ids[] table are the only entries without a comment which model they apply to. Add these comments.
The Asus TF103C entry also is in the wrong place for what is supposed to be an alphabetically sorted list. Move it up so that the list is properly sorted and add a comment that the list is alphabetically sorted.
--- drivers/acpi/x86/utils.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/acpi/x86/utils.c +10 -7
@@ -288,6 +288,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {/* * 2. Devices which also have the skip i2c/serdev quirks and which * need the x86-android-tablets module to properly work. +* Sorted alphabetically. */ #if IS_ENABLED (CONFIG_X86_ANDROID_TABLETS ) {
@@ -313,6 +314,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS), }, { +/* Asus ME176C tablet */ .matches = {DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
@@ -323,23 +325,24 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS), }, { -/* Lenovo Yoga Book X90F/L */ +/* Asus TF103C transformer 2-in-1 */ .matches = { -DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"Intel Corporation" ), -DMI_EXACT_MATCH (DMI_PRODUCT_NAME ,"CHERRYVIEW D1 PLATFORM" ), - DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), }, .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | -ACPI_QUIRK_UART1_SKIP |ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY | ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS), }, { +/* Lenovo Yoga Book X90F/L */ .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), - DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), +DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"Intel Corporation" ), +DMI_EXACT_MATCH (DMI_PRODUCT_NAME ,"CHERRYVIEW D1 PLATFORM" ), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), }, .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | +ACPI_QUIRK_UART1_SKIP |ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY | ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS), },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 301/356 LoongArch: Fix sleeping in atomic context for PREEMPT_RT
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
[ Upstream commit 88fd2b70120d52c1010257d36776876941375490 ]
Commit bab1c299f3945ffe79 ("LoongArch: Fix sleeping in atomic context in setup_tlb_handler()") changes the gfp flag from GFP_KERNEL to GFP_ATOMIC for alloc_pages_node(). However, for PREEMPT_RT kernels we can still get a "sleeping in atomic context" error:
[ 0.372259] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
[ 0.372266] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/1
[ 0.372268] preempt_count: 1, expected: 0
[ 0.372270] RCU nest depth: 1, expected: 1
[ 0.372272] 3 locks held by swapper/1/0:
[ 0.372274] #0: 900000000c9f5e60 (&pcp->lock){+.+.}-{3:3}, at: get_page_from_freelist+0x524/0x1c60
[ 0.372294] #1: 90000000087013b8 (rcu_read_lock){....}-{1:3}, at: rt_spin_trylock+0x50/0x140
[ 0.372305] #2: 900000047fffd388 (&zone->lock){+.+.}-{3:3}, at: __rmqueue_pcplist+0x30c/0xea0
[ 0.372314] irq event stamp: 0
[ 0.372316] hardirqs last enabled at (0): [<0000000000000000>] 0x0
[ 0.372322] hardirqs last disabled at (0): [<9000000005947320>] copy_process+0x9c0/0x26e0
[ 0.372329] softirqs last enabled at (0): [<9000000005947320>] copy_process+0x9c0/0x26e0
[ 0.372335] softirqs last disabled at (0): [<0000000000000000>] 0x0
[ 0.372341] CPU: 1 UID: 0 PID: 0 Comm: swapper/1 Not tainted 6.12.0-rc7+ #1891
[ 0.372346] Hardware name: Loongson Loongson-3A5000-7A1000-1w-CRB/Loongson-LS3A5000-7A1000-1w-CRB, BIOS vUDK2018-LoongArch-V2.0.0-prebeta9 10/21/2022
[ 0.372349] Stack : 0000000000000089 9000000005a0db9c 90000000071519c8 9000000100388000
[ 0.372486] 900000010038b890 0000000000000000 900000010038b898 9000000007e53788
[ 0.372492] 900000000815bcc8 900000000815bcc0 900000010038b700 0000000000000001
[ 0.372498] 0000000000000001 4b031894b9d6b725 00000000055ec000 9000000100338fc0
[ 0.372503] 00000000000000c4 0000000000000001 000000000000002d 0000000000000003
[ 0.372509] 0000000000000030 0000000000000003 00000000055ec000 0000000000000003
[ 0.372515] 900000000806d000 9000000007e53788 00000000000000b0 0000000000000004
[ 0.372521] 0000000000000000 0000000000000000 900000000c9f5f10 0000000000000000
[ 0.372526] 90000000076f12d8 9000000007e53788 9000000005924778 0000000000000000
[ 0.372532] 00000000000000b0 0000000000000004 0000000000000000 0000000000070000
[ 0.372537] ...
[ 0.372540] Call Trace:
[ 0.372542] [<9000000005924778>] show_stack+0x38/0x180
[ 0.372548] [<90000000071519c4>] dump_stack_lvl+0x94/0xe4
[ 0.372555] [<900000000599b880>] __might_resched+0x1a0/0x260
[ 0.372561] [<90000000071675cc>] rt_spin_lock+0x4c/0x140
[ 0.372565] [<9000000005cbb768>] __rmqueue_pcplist+0x308/0xea0
[ 0.372570] [<9000000005cbed84>] get_page_from_freelist+0x564/0x1c60
[ 0.372575] [<9000000005cc0d98>] __alloc_pages_noprof+0x218/0x1820
[ 0.372580] [<900000000593b36c>] tlb_init+0x1ac/0x298
[ 0.372585] [<9000000005924b74>] per_cpu_trap_init+0x114/0x140
[ 0.372589] [<9000000005921964>] cpu_probe+0x4e4/0xa60
[ 0.372592] [<9000000005934874>] start_secondary+0x34/0xc0
[ 0.372599] [<900000000715615c>] smpboot_entry+0x64/0x6cThis is because in PREEMPT_RT kernels normal spinlocks are replaced by rt spinlocks and rt_spin_lock() will cause sleeping. Fix it by disabling NUMA optimization completely for PREEMPT_RT kernels.
--- arch/loongarch/mm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/loongarch/mm/tlb.c +1 -1
@@ -292,7 +292,7 @@ static void setup_tlb_handler(int cpu)/* Avoid lockdep warning */ rcu_cpu_starting (cpu); -#ifdef CONFIG_NUMA +#if defined(CONFIG_NUMA ) && !defined(CONFIG_PREEMPT_RT ) vec_sz =sizeof (exception_handlers);if (pcpu_handlers[cpu])
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 302/356 fs/ntfs3: Fix case when unmarked clusters intersect with zone
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <[email protected]>
[ Upstream commit 5fc982fe7eca9d0cf7b25832450ebd4f7c8e1c36 ]
--- fs/ntfs3/run.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
fs/ntfs3/run.c +30 -10
@@ -1053,8 +1053,8 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, {int ret, err;CLST next_vcn, lcn, len; -size_t index; -bool ok; +size_t index, done; +bool ok, zone;struct wnd_bitmap *wnd; ret =run_unpack (run, sbi, ino, svcn, evcn, vcn, run_buf, run_buf_size);
@@ -1085,8 +1085,9 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,continue ;down_read_nested (&wnd->rw_lock,BITMAP_MUTEX_CLUSTERS ); + zone =max (wnd->zone_bit, lcn) <min (wnd->zone_end, lcn + len);/* Check for free blocks. */ - ok =wnd_is_used (wnd, lcn, len); + ok = !zone &&wnd_is_used (wnd, lcn, len);up_read (&wnd->rw_lock);if (ok)continue ;
@@ -1094,14 +1095,33 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,/* Looks like volume is corrupted. */ ntfs_set_state (sbi,NTFS_DIRTY_ERROR ); -if (down_write_trylock (&wnd->rw_lock)) { -/* Mark all zero bits as used in range [lcn, lcn+len). */ -size_t done; - err =wnd_set_used_safe (wnd, lcn, len, &done); -up_write (&wnd->rw_lock); -if (err) -return err; +if (!down_write_trylock (&wnd->rw_lock)) +continue ; + +if (zone) { +/* +* Range [lcn, lcn + len) intersects with zone. +* To avoid complex with zone just turn it off. +*/ +wnd_zone_set (wnd,0 ,0 ); + } + +/* Mark all zero bits as used in range [lcn, lcn+len). */ + err =wnd_set_used_safe (wnd, lcn, len, &done); +if (zone) { +/* Restore zone. Lock mft run. */ +struct rw_semaphore *lock; + lock =is_mounted (sbi) ? &sbi->mft.ni->file.run_lock : +NULL ; +if (lock) +down_read (lock); +ntfs_refresh_zone (sbi); +if (lock) +up_read (lock); } +up_write (&wnd->rw_lock); +if (err) +return err; }return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 303/356 usb: chipidea: udc: handle USB Error Interrupt if IOC not set
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
[ Upstream commit 548f48b66c0c5d4b9795a55f304b7298cde2a025 ]
As per USBSTS register description about UEI:
When completion of a USB transaction results in an error condition, this bit is set by the Host/Device Controller. This bit is set along with the USBINT bit, if the TD on which the error interrupt occurred also had its interrupt on complete (IOC) bit set.
UI is set only when IOC set. Add checking UEI to fix miss call isr_tr_complete_handler() when IOC have not set and transfer error happen.
--- drivers/usb/chipidea/udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/chipidea/udc.c +1 -1
@@ -2062,7 +2062,7 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci) } } -if (USBi_UI & intr) +if ((USBi_UI | USBi_UEI) & intr)isr_tr_complete_handler (ci);if ((USBi_SLI & intr) && !(ci->suspended)) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 304/356 iio: light: ltr501: Add LTER0303 to the supported devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit c26acb09ccbef47d1fddaf0783c1392d0462122c ]
It has been found that the (non-vendor issued) ACPI ID for Lite-On LTR303 is present in Microsoft catalog. Add it to the list of the supported devices.
--- drivers/iio/light/ltr501.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iio/light/ltr501.c +2 -0
@@ -1612,6 +1612,8 @@ static const struct acpi_device_id ltr_acpi_match[] = { { "LTER0501", ltr501 }, { "LTER0559", ltr559 }, { "LTER0301", ltr301 }, +/* https://www.catalog.update.microsoft.com/Search.aspx?q=lter0303 */ + { "LTER0303", ltr303 }, { }, };MODULE_DEVICE_TABLE (acpi, ltr_acpi_match);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 305/356 ASoC: amd: yc: fix internal mic on Redmi G 2022
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Far <[email protected]>
[ Upstream commit 67a0463d339059eeeead9cd015afa594659cfdaf ]
This laptop model requires an additional detection quirk to enable the internal microphone
--- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
@@ -416,6 +416,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Xiaomi Book Pro 14 2022"), } }, + { + .driver_data = &acp6x_card, + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"TIMI" ), + DMI_MATCH(DMI_PRODUCT_NAME, "Redmi G 2022"), + } + }, { .driver_data = &acp6x_card, .matches = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 306/356 drm/amdgpu/vcn: reset fw_shared when VCPU buffers corrupted on vcn v4.0.3
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Liu <[email protected]>
[ Upstream commit 928cd772e18ffbd7723cb2361db4a8ccf2222235 ]
It is not necessarily corrupted. When there is RAS fatal error, device memory access is blocked. Hence vcpu bo cannot be saved to system memory as in a regular suspend sequence before going for reset. In other full device reset cases, that gets saved and restored during resume.
v2: Remove redundant code like vcn_v4_0 did
v2: Refine commit message
v3: Drop the volatile
v3: Refine commit message
--- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 30 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +22 -8
@@ -77,6 +77,20 @@ static int vcn_v4_0_3_early_init(void *handle)return amdgpu_vcn_early_init (adev); } +static int vcn_v4_0_3_fw_shared_init (struct amdgpu_device *adev,int inst_idx) +{ +struct amdgpu_vcn4_fw_shared *fw_shared; + + fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; + fw_shared->present_flag_0 =cpu_to_le32 (AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE ); + fw_shared->sq.is_enabled =1 ; + +if (amdgpu_vcnfw_log) +amdgpu_vcn_fwlog_init (&adev->vcn.inst[inst_idx]); + +return 0 ; +} +/** * vcn_v4_0_3_sw_init - sw init for VCN block *
@@ -107,8 +121,6 @@ static int vcn_v4_0_3_sw_init(void *handle)return r;for (i =0 ; i < adev->vcn.num_vcn_inst; i++) { -volatile struct amdgpu_vcn4_fw_shared *fw_shared; - vcn_inst =GET_INST (VCN , i); ring = &adev->vcn.inst[i].ring_enc[0 ];
@@ -131,12 +143,7 @@ static int vcn_v4_0_3_sw_init(void *handle)if (r)return r; - fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; - fw_shared->present_flag_0 =cpu_to_le32 (AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE ); - fw_shared->sq.is_enabled = true; - -if (amdgpu_vcnfw_log) -amdgpu_vcn_fwlog_init (&adev->vcn.inst[i]); +vcn_v4_0_3_fw_shared_init (adev, i); }if (amdgpu_sriov_vf (adev)) {
@@ -221,6 +228,8 @@ static int vcn_v4_0_3_hw_init(void *handle) } }else {for (i =0 ; i < adev->vcn.num_vcn_inst; ++i) { +struct amdgpu_vcn4_fw_shared *fw_shared; + vcn_inst =GET_INST (VCN , i); ring = &adev->vcn.inst[i].ring_enc[0 ];
@@ -244,6 +253,11 @@ static int vcn_v4_0_3_hw_init(void *handle) regVCN_RB1_DB_CTRL); } +/* Re-init fw_shared when RAS fatal error occurred */ + fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; +if (!fw_shared->sq.is_enabled) +vcn_v4_0_3_fw_shared_init (adev, i); + r =amdgpu_ring_test_helper (ring);if (r) goto done;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 307/356 MIPS: Loongson64: DTS: Really fix PCIe port nodes for ls7a
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xi Ruoyao <[email protected]>
[ Upstream commit 4fbd66d8254cedfd1218393f39d83b6c07a01917 ]
Fix the dtc warnings:
arch/mips/boot/dts/loongson/ls7a-pch.dtsi:68.16-416.5: Warning (interrupt_provider): /bus@10000000/pci@1a000000: '#interrupt-cells' found, but node is not an interrupt provider
arch/mips/boot/dts/loongson/ls7a-pch.dtsi:68.16-416.5: Warning (interrupt_provider): /bus@10000000/pci@1a000000: '#interrupt-cells' found, but node is not an interrupt provider
arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'And a runtime warning introduced in commit 045b14ca5c36 ("of: WARN on deprecated #address-cells/#size-cells handling"):
WARNING: CPU: 0 PID: 1 at drivers/of/base.c:106 of_bus_n_addr_cells+0x9c/0xe0
Missing '#address-cells' in /bus@10000000/pci@1a000000/pci_bridge@9,0The fix is similar to commit d89a415ff8d5 ("MIPS: Loongson64: DTS: Fix PCIe port nodes for ls7a"), which has fixed the issue for ls2k (despite its subject mentions ls7a).
--- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 73 +++++++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-)
arch/mips/boot/dts/loongson/ls7a-pch.dtsi +60 -13
@@ -70,7 +70,6 @@ device_type = "pci"; #address-cells = <3>; #size-cells = <2>; - #interrupt-cells = <2>; msi-parent = <&msi>; reg = <0 0x1a000000 0 0x02000000>,
@@ -234,7 +233,7 @@ }; }; - pci_bridge@9,0 { + pcie@9,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400",
@@ -244,12 +243,16 @@ interrupts = <32 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 32 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@a,0 { + pcie@a,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400",
@@ -259,12 +262,16 @@ interrupts = <33 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 33 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@b,0 { + pcie@b,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400",
@@ -274,12 +281,16 @@ interrupts = <34 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 34 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@c,0 { + pcie@c,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400",
@@ -289,12 +300,16 @@ interrupts = <35 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 35 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@d,0 { + pcie@d,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400",
@@ -304,12 +319,16 @@ interrupts = <36 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 36 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@e,0 { + pcie@e,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400",
@@ -319,12 +338,16 @@ interrupts = <37 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 37 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@f,0 { + pcie@f,0 { compatible = "pci0014,7a29.1", "pci0014,7a29", "pciclass060400",
@@ -334,12 +357,16 @@ interrupts = <40 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 40 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@10,0 { + pcie@10,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400",
@@ -349,12 +376,16 @@ interrupts = <41 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 41 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@11,0 { + pcie@11,0 { compatible = "pci0014,7a29.1", "pci0014,7a29", "pciclass060400",
@@ -364,12 +395,16 @@ interrupts = <42 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 42 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@12,0 { + pcie@12,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400",
@@ -379,12 +414,16 @@ interrupts = <43 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 43 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@13,0 { + pcie@13,0 { compatible = "pci0014,7a29.1", "pci0014,7a29", "pciclass060400",
@@ -394,12 +433,16 @@ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 38 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@14,0 { + pcie@14,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400",
@@ -409,9 +452,13 @@ interrupts = <39 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 39 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 308/356 ASoC: amd: yc: Add quirk for microphone on Lenovo Thinkpad T14s Gen 6 21M1CTO1WW
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit cbc86dd0a4fe9f8c41075328c2e740b68419d639 ]
Add a quirk for Tova's Lenovo Thinkpad T14s with product name 21M1.
--- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
@@ -220,6 +220,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), } }, + { + .driver_data = &acp6x_card, + .matches = { +DMI_MATCH (DMI_BOARD_VENDOR ,"LENOVO" ), + DMI_MATCH(DMI_PRODUCT_NAME, "21M1"), + } + }, { .driver_data = &acp6x_card, .matches = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 309/356 powerpc/prom_init: Fixup missing powermac #size-cells
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
[ Upstream commit cf89c9434af122f28a3552e6f9cc5158c33ce50a ]
On some powermacs escc nodes are missing #size-cells properties, which is deprecated and now triggers a warning at boot since commit 045b14ca5c36 ("of: WARN on deprecated #address-cells/#size-cells handling").
For example:
Missing '#size-cells' in /pci@f2000000/mac-io@c/escc@13000
WARNING: CPU: 0 PID: 0 at drivers/of/base.c:133 of_bus_n_size_cells+0x98/0x108
Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
...
Call Trace:
of_bus_n_size_cells+0x98/0x108 (unreliable)
of_bus_default_count_cells+0x40/0x60
__of_get_address+0xc8/0x21c
__of_address_to_resource+0x5c/0x228
pmz_init_port+0x5c/0x2ec
pmz_probe.isra.0+0x144/0x1e4
pmz_console_init+0x10/0x48
console_init+0xcc/0x138
start_kernel+0x5c4/0x694As powermacs boot via prom_init it's possible to add the missing properties to the device tree during boot, avoiding the warning. Note that escc-legacy nodes are also missing #size-cells properties, but they are skipped by the macio driver, so leave them alone.
Depends-on: 045b14ca5c36 ("of: WARN on deprecated #address-cells/#size-cells handling")
--- arch/powerpc/kernel/prom_init.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
arch/powerpc/kernel/prom_init.c +27 -2
@@ -2924,7 +2924,7 @@ static void __init fixup_device_tree_chrp(void)#endif #if defined(CONFIG_PPC64 ) && defined(CONFIG_PPC_PMAC ) -static void __init fixup_device_tree_pmac (void ) +static void __init fixup_device_tree_pmac64 (void ) {phandle u3, i2c, mpic;u32 u3_rev;
@@ -2964,7 +2964,31 @@ static void __init fixup_device_tree_pmac(void) &parent, sizeof(parent)); }#else -#define fixup_device_tree_pmac () +#define fixup_device_tree_pmac64 () +#endif + +#ifdef CONFIG_PPC_PMAC +static void __init fixup_device_tree_pmac (void ) +{ +__be32 val =1 ; +char type[8 ]; +phandle node; + +// Some pmacs are missing #size-cells on escc nodes +for (node =0 ;prom_next_node (&node); ) { + type[0 ] ='\0' ; +prom_getprop (node,"device_type" , type,sizeof (type)); +if (prom_strcmp (type,"escc" )) +continue ; + +if (prom_getproplen (node,"#size-cells" ) !=PROM_ERROR ) +continue ; + +prom_setprop (node,NULL ,"#size-cells" , &val,sizeof (val)); + } +} +#else +static inline void fixup_device_tree_pmac (void ) { }#endif #ifdef CONFIG_PPC_EFIKA
@@ -3189,6 +3213,7 @@ static void __init fixup_device_tree(void)fixup_device_tree_maple_memory_controller ();fixup_device_tree_chrp ();fixup_device_tree_pmac (); +fixup_device_tree_pmac64 ();fixup_device_tree_efika ();fixup_device_tree_pasemi (); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 310/356 misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Parker Newman <[email protected]>
[ Upstream commit 7738a7ab9d12c5371ed97114ee2132d4512e9fd5 ]
Add a quirk similar to eeprom_93xx46 to add an extra clock cycle before reading data from the EEPROM.
The 93Cx6 family of EEPROMs output a "dummy 0 bit" between the writing of the op-code/address from the host to the EEPROM and the reading of the actual data from the EEPROM.
More info can be found on page 6 of the AT93C46 datasheet (linked below). Similar notes are found in other 93xx6 datasheets.
In summary the read operation for a 93Cx6 EEPROM is:
Write to EEPROM: 110[A5-A0] (9 bits)
Read from EEPROM: 0[D15-D0] (17 bits)
Where:
110 is the start bit and READ OpCode [A5-A0] is the address to read from 0 is a "dummy bit" preceding the actual data [D15-D0] is the actual data.
Looking at the READ timing diagrams in the 93Cx6 datasheets the dummy bit should be clocked out on the last address bit clock cycle meaning it should be discarded naturally.
However, depending on the hardware configuration sometimes this dummy bit is not discarded. This is the case with Exar PCI UARTs which require an extra clock cycle between sending the address and reading the data.
Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-5193-SEEPROM-AT93C46D-Datasheet.pdf
--- drivers/misc/eeprom/eeprom_93cx6.c | 10 ++++++++++ include/linux/eeprom_93cx6.h | 11 +++++++++++ 2 files changed, 21 insertions(+)
drivers/misc/eeprom/eeprom_93cx6.c +10 -0
@@ -186,6 +186,11 @@ void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,eeprom_93cx6_write_bits (eeprom, command,PCI_EEPROM_WIDTH_OPCODE + eeprom->width); +if (has_quirk_extra_read_cycle (eeprom)) { +eeprom_93cx6_pulse_high (eeprom); +eeprom_93cx6_pulse_low (eeprom); + } +/* * Read the requested 16 bits. */
@@ -252,6 +257,11 @@ void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte,eeprom_93cx6_write_bits (eeprom, command,PCI_EEPROM_WIDTH_OPCODE + eeprom->width +1 ); +if (has_quirk_extra_read_cycle (eeprom)) { +eeprom_93cx6_pulse_high (eeprom); +eeprom_93cx6_pulse_low (eeprom); + } +/* * Read the requested 8 bits. */
include/linux/eeprom_93cx6.h +11 -0
@@ -11,6 +11,8 @@Supported chipsets: 93c46, 93c56 and 93c66. */ +#include <linux/bits.h> +/* * EEPROM operation defines. */
@@ -34,6 +36,7 @@* @register_write(struct eeprom_93cx6 *eeprom): handler to * write to the eeprom register by using all reg_* fields. * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines +* @quirks: eeprom or controller quirks * @drive_data: Set if we're driving the data line. * @reg_data_in: register field to indicate data input * @reg_data_out: register field to indicate data output
@@ -50,6 +53,9 @@ struct eeprom_93cx6 {void (*register_write)(struct eeprom_93cx6 *eeprom);int width; +unsigned int quirks; +/* Some EEPROMs require an extra clock cycle before reading */ +#define PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE BIT(0)char drive_data;char reg_data_in;
@@ -71,3 +77,8 @@ extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable);extern void eeprom_93cx6_write (struct eeprom_93cx6 *eeprom,u8 addr,u16 data); + +static inline bool has_quirk_extra_read_cycle (struct eeprom_93cx6 *eeprom) +{ +return eeprom->quirks &PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE ; +}
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 311/356 rtc: cmos: avoid taking rtc_lock for extended period of time
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
[ Upstream commit 0a6efab33eab4e973db26d9f90c3e97a7a82e399 ]
On my device reading entirety of /sys/devices/pnp0/00:03/cmos_nvram0/nvmem takes about 9 msec during which time interrupts are off on the CPU that does the read and the thread that performs the read can not be migrated or preempted by another higher priority thread (RT or not).
Allow readers and writers be preempted by taking and releasing rtc_lock spinlock for each individual byte read or written rather than once per read/write request.
--- drivers/rtc/rtc-cmos.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-)
drivers/rtc/rtc-cmos.c +15 -16
@@ -645,18 +645,17 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val,unsigned char *buf = val; off +=NVRAM_OFFSET ; -spin_lock_irq (&rtc_lock); -for (; count; count--, off++) { +for (; count; count--, off++, buf++) { +guard (spinlock_irq)(&rtc_lock);if (off <128 ) - *buf++ =CMOS_READ (off); + *buf =CMOS_READ (off);else if (can_bank2) - *buf++ =cmos_read_bank2 (off); + *buf =cmos_read_bank2 (off);else -break ; +return -EIO ; } -spin_unlock_irq (&rtc_lock); -return count ? -EIO :0 ; +return 0 ; } static int cmos_nvram_write(void *priv, unsigned int off, void *val,
@@ -671,23 +670,23 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val,* NVRAM to update, updating checksums is also part of its job. */ off +=NVRAM_OFFSET ; -spin_lock_irq (&rtc_lock); -for (; count; count--, off++) { +for (; count; count--, off++, buf++) {/* don't trash RTC registers */ if (off == cmos->day_alrm || off == cmos->mon_alrm || off == cmos->century) - buf++; -else if (off <128 ) -CMOS_WRITE (*buf++, off); +continue ; + +guard (spinlock_irq)(&rtc_lock); +if (off <128 ) +CMOS_WRITE (*buf, off);else if (can_bank2) -cmos_write_bank2 (*buf++, off); +cmos_write_bank2 (*buf, off);else -break ; +return -EIO ; } -spin_unlock_irq (&rtc_lock); -return count ? -EIO :0 ; +return 0 ; }/*----------------------------------------------------------------*/
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 312/356 serial: 8250_dw: Add Sophgo SG2044 quirk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Inochi Amaoto <[email protected]>
[ Upstream commit cad4dda82c7eedcfc22597267e710ccbcf39d572 ]
SG2044 relys on an internal divisor when calculating bitrate, which means a wrong clock for the most common bitrates. So add a quirk for this uart device to skip the set rate call and only relys on the internal UART divisor.
--- drivers/tty/serial/8250/8250_dw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/tty/serial/8250/8250_dw.c +3 -2
@@ -785,7 +785,7 @@ static const struct dw8250_platform_data dw8250_renesas_rzn1_data = { .quirks = DW_UART_QUIRK_CPR_VALUE | DW_UART_QUIRK_IS_DMA_FC, }; -static const struct dw8250_platform_data dw8250_starfive_jh7100_data = { +static const struct dw8250_platform_data dw8250_skip_set_rate_data = { .usr_reg =DW_UART_USR , .quirks =DW_UART_QUIRK_SKIP_SET_RATE , };
@@ -795,7 +795,8 @@ static const struct of_device_id dw8250_of_match[] = { { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data }, { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data }, { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data }, - { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data }, + { .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data }, + { .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data }, {/* Sentinel */ } };MODULE_DEVICE_TABLE (of, dw8250_of_match);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 313/356 smb: client: dont try following DFS links in cifs_tree_connect()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
[ Upstream commit 36008fe6e3dc588e5e9ceae6e82c7f69399eb5d8 ]
We can't properly support chasing DFS links in cifs_tree_connect() because
(1) We don't support creating new sessions while we're reconnecting, which would be required for DFS interlinks.
(2) ->is_path_accessible() can't be called from cifs_tree_connect() as it would deadlock with smb2_reconnect(). This is required for checking if new DFS target is a nested DFS link.
By unconditionally trying to get an DFS referral from new DFS target isn't correct because if the new DFS target (interlink) is an DFS standalone namespace, then we would end up getting -ELOOP and then potentially leaving tcon disconnected.
--- fs/smb/client/dfs.c | 188 ++++---------------------------------------- 1 file changed, 17 insertions(+), 171 deletions(-)
fs/smb/client/dfs.c +17 -171
@@ -324,49 +324,6 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)return rc; } -/* Update dfs referral path of superblock */ -static int update_server_fullpath (struct TCP_Server_Info *server,struct cifs_sb_info *cifs_sb, -const char *target) -{ -int rc =0 ; -size_t len =strlen (target); -char *refpath, *npath; - -if (unlikely (len <2 || *target !='\\' )) -return -EINVAL ; - -if (target[1 ] =='\\' ) { - len +=1 ; - refpath =kmalloc (len,GFP_KERNEL ); -if (!refpath) -return -ENOMEM ; - -scnprintf (refpath, len,"%s" , target); - }else { - len +=sizeof ("\\" ); - refpath =kmalloc (len,GFP_KERNEL ); -if (!refpath) -return -ENOMEM ; - -scnprintf (refpath, len,"\\%s" , target); - } - - npath =dfs_cache_canonical_path (refpath, cifs_sb->local_nls,cifs_remap (cifs_sb)); -kfree (refpath); - -if (IS_ERR (npath)) { - rc =PTR_ERR (npath); - }else { -mutex_lock (&server->refpath_lock); -spin_lock (&server->srv_lock); -kfree (server->leaf_fullpath); - server->leaf_fullpath = npath; -spin_unlock (&server->srv_lock); -mutex_unlock (&server->refpath_lock); - } -return rc; -} -static int target_share_matches_server (struct TCP_Server_Info *server,char *share,bool *target_match) {
@@ -391,77 +348,22 @@ static int target_share_matches_server(struct TCP_Server_Info *server, char *shareturn rc; } -static void __tree_connect_ipc (const unsigned int xid,char *tree, -struct cifs_sb_info *cifs_sb, -struct cifs_ses *ses) -{ -struct TCP_Server_Info *server = ses->server; -struct cifs_tcon *tcon = ses->tcon_ipc; -int rc; - -spin_lock (&ses->ses_lock); -spin_lock (&ses->chan_lock); -if (cifs_chan_needs_reconnect (ses, server) || - ses->ses_status !=SES_GOOD ) { -spin_unlock (&ses->chan_lock); -spin_unlock (&ses->ses_lock); -cifs_server_dbg (FYI ,"%s: skipping ipc reconnect due to disconnected ses\n" , - __func__); -return ; - } -spin_unlock (&ses->chan_lock); -spin_unlock (&ses->ses_lock); - -cifs_server_lock (server); -scnprintf (tree,MAX_TREE_SIZE ,"\\\\%s\\IPC$" , server->hostname); -cifs_server_unlock (server); - - rc = server->ops->tree_connect (xid, ses, tree, tcon, - cifs_sb->local_nls); -cifs_server_dbg (FYI ,"%s: tree_reconnect %s: %d\n" , __func__, tree, rc); -spin_lock (&tcon->tc_lock); -if (rc) { - tcon->status =TID_NEED_TCON ; - }else { - tcon->status =TID_GOOD ; - tcon->need_reconnect = false; - } -spin_unlock (&tcon->tc_lock); -} - -static void tree_connect_ipc (const unsigned int xid,char *tree, -struct cifs_sb_info *cifs_sb, -struct cifs_tcon *tcon) -{ -struct cifs_ses *ses = tcon->ses; - -__tree_connect_ipc (xid, tree, cifs_sb, ses); -__tree_connect_ipc (xid, tree, cifs_sb,CIFS_DFS_ROOT_SES (ses)); -} - -static int __tree_connect_dfs_target (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,char *tree,bool islink, -struct dfs_cache_tgt_list *tl) +static int tree_connect_dfs_target (const unsigned int xid, +struct cifs_tcon *tcon, +struct cifs_sb_info *cifs_sb, +char *tree,bool islink, +struct dfs_cache_tgt_list *tl) { -int rc; +const struct smb_version_operations *ops = tcon->ses->server->ops;struct TCP_Server_Info *server = tcon->ses->server; -const struct smb_version_operations *ops = server->ops; -struct cifs_ses *root_ses =CIFS_DFS_ROOT_SES (tcon->ses); -char *share =NULL , *prefix =NULL ;struct dfs_cache_tgt_iterator *tit; +char *share =NULL , *prefix =NULL ;bool target_match; - - tit =dfs_cache_get_tgt_iterator (tl); -if (!tit) { - rc = -ENOENT ; - goto out; - } +int rc = -ENOENT ;/* Try to tree connect to all dfs targets */ -for (; tit; tit =dfs_cache_get_next_tgt (tl, tit)) { -const char *target =dfs_cache_get_tgt_name (tit); -DFS_CACHE_TGT_LIST (ntl); - +for (tit =dfs_cache_get_tgt_iterator (tl); + tit; tit =dfs_cache_get_next_tgt (tl, tit)) {kfree (share);kfree (prefix); share = prefix =NULL ;
@@ -482,69 +384,16 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t }dfs_cache_noreq_update_tgthint (server->leaf_fullpath +1 , tit); -tree_connect_ipc (xid, tree, cifs_sb, tcon); -scnprintf (tree,MAX_TREE_SIZE ,"\\%s" , share); -if (!islink) { - rc = ops->tree_connect (xid, tcon->ses, tree, tcon, cifs_sb->local_nls); -break ; - } - -/* -* If no dfs referrals were returned from link target, then just do a TREE_CONNECT -* to it. Otherwise, cache the dfs referral and then mark current tcp ses for -* reconnect so either the demultiplex thread or the echo worker will reconnect to -* newly resolved target. -*/ -if (dfs_cache_find (xid, root_ses, cifs_sb->local_nls,cifs_remap (cifs_sb), target, -NULL , &ntl)) { - rc = ops->tree_connect (xid, tcon->ses, tree, tcon, cifs_sb->local_nls); -if (rc) -continue ; - + rc = ops->tree_connect (xid, tcon->ses, tree, + tcon, tcon->ses->local_nls); +if (islink && !rc && cifs_sb) rc =cifs_update_super_prepath (cifs_sb, prefix); - }else { -/* Target is another dfs share */ - rc =update_server_fullpath (server, cifs_sb, target); -dfs_cache_free_tgts (tl); - -if (!rc) { - rc = -EREMOTE ; -list_replace_init (&ntl.tl_list, &tl->tl_list); - }else -dfs_cache_free_tgts (&ntl); - }break ; } -out:kfree (share);kfree (prefix); - -return rc; -} - -static int tree_connect_dfs_target (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,char *tree,bool islink, -struct dfs_cache_tgt_list *tl) -{ -int rc; -int num_links =0 ; -struct TCP_Server_Info *server = tcon->ses->server; -char *old_fullpath = server->leaf_fullpath; - -do { - rc =__tree_connect_dfs_target (xid, tcon, cifs_sb, tree, islink, tl); -if (!rc || rc != -EREMOTE ) -break ; - }while (rc = -ELOOP , ++num_links <MAX_NESTED_LINKS ); -/* -* If we couldn't tree connect to any targets from last referral path, then -* retry it from newly resolved dfs referral. -*/ -if (rc && server->leaf_fullpath != old_fullpath) -cifs_signal_cifsd_for_reconnect (server, true); -dfs_cache_free_tgts (tl);return rc; }
@@ -599,14 +448,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struif (!IS_ERR (sb)) cifs_sb =CIFS_SB (sb); -/* -* Tree connect to last share in @tcon->tree_name whether dfs super or -* cached dfs referral was not found. -*/ -if (!cifs_sb || !server->leaf_fullpath || +/* Tree connect to last share in @tcon->tree_name if no DFS referral */ +if (!server->leaf_fullpath ||dfs_cache_noreq_find (server->leaf_fullpath +1 , &ref, &tl)) { - rc = ops->tree_connect (xid, tcon->ses, tcon->tree_name, tcon, - cifs_sb ? cifs_sb->local_nls : nlsc); + rc = ops->tree_connect (xid, tcon->ses, tcon->tree_name, + tcon, tcon->ses->local_nls); goto out; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 314/356 setlocalversion: work around "git describe" performance
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rasmus Villemoes <[email protected]>
[ Upstream commit 523f3dbc187a9618d4fd80c2b438e4d490705dcd ]
Contrary to expectations, passing a single candidate tag to "git describe" is slower than not passing any --match options.
$ time git describe --debug ... traversed 10619 commits ... v6.12-rc5-63-g0fc810ae3ae1
real 0m0.169s
$ time git describe --match=v6.12-rc5 --debug ... traversed 1310024 commits v6.12-rc5-63-g0fc810ae3ae1
real 0m1.281s
In fact, the --debug output shows that git traverses all or most of history. For some repositories and/or git versions, those 1.3s are actually 10-15 seconds.
This has been acknowledged as a performance bug in git [1], and a fix is on its way [2]. However, no solution is yet in git.git, and even when one lands, it will take quite a while before it finds its way to a release and for $random_kernel_developer to pick that up.
So rewrite the logic to use plumbing commands. For each of the candidate values of $tag, we ask: (1) is $tag even an annotated tag? (2) Is it eligible to describe HEAD, i.e. an ancestor of HEAD? (3) If so, how many commits are in $tag..HEAD?
I have tested that this produces the same output as the current script for ~700 random commits between v6.9..v6.10. For those 700 commits, and in my git repo, the 'make -s kernelrelease' command is on average ~4 times faster with this patch applied (geometric mean of ratios).
For the commit mentioned in Josh's original report [3], the time-consuming part of setlocalversion goes from
$ time git describe --match=v6.12-rc5 c1e939a21eb1 v6.12-rc5-44-gc1e939a21eb1
real 0m1.210s
to
$ time git rev-list --count --left-right v6.12-rc5..c1e939a21eb1 0 44
real 0m0.037s
[1] https://lore.kernel.org/git/[email protected]/
[2] https://lore.kernel.org/git/[email protected]/
[3] https://lore.kernel.org/lkml/309549cafdcfe50c4fceac3263220cc3d8b109b2.1730337435.git.jpoimboe@kernel.org/
--- scripts/setlocalversion | 54 +++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 16 deletions(-)
scripts/setlocalversion +38 -16
@@ -30,6 +30,27 @@ if test $# -gt 0 -o ! -d "$srctree"; then usage fi +try_tag() { + tag="$1" + + # Is $tag an annotated tag? + [ "$(git cat-file -t "$tag" 2> /dev/null)" = tag ] || return 1 + + # Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD? + # shellcheck disable=SC2046 # word splitting is the point here + set -- $(git rev-list --count --left-right "$tag"...HEAD 2> /dev/null) + + # $1 is 0 if and only if $tag is an ancestor of HEAD. Use + # string comparison, because $1 is empty if the 'git rev-list' + # command somehow failed. + [ "$1" = 0 ] || return 1 + + # $2 is the number of commits in the range $tag..HEAD, possibly 0. + count="$2" + + return 0 +} + scm_version() { local short=false
@@ -61,33 +82,33 @@ scm_version() # stable kernel: 6.1.7 -> v6.1.7 version_tag=v$(echo "${KERNELVERSION}" | sed -E 's/^([0-9]+\.[0-9]+)\.0(.*)$/\1\2/') + # try_tag initializes count if the tag is usable. + count= + # If a localversion* file exists, and the corresponding # annotated tag exists and is an ancestor of HEAD, use # it. This is the case in linux-next. - tag=${file_localversion#-} - desc= - if [ -n "${tag}" ]; then - desc=$(git describe --match=$tag 2>/dev/null) + if [ -n "${file_localversion#-}" ] ; then + try_tag "${file_localversion#-}" fi # Otherwise, if a localversion* file exists, and the tag # obtained by appending it to the tag derived from # KERNELVERSION exists and is an ancestor of HEAD, use # it. This is e.g. the case in linux-rt. - if [ -z "${desc}" ] && [ -n "${file_localversion}" ]; then - tag="${version_tag}${file_localversion}" - desc=$(git describe --match=$tag 2>/dev/null) + if [ -z "${count}" ] && [ -n "${file_localversion}" ]; then + try_tag "${version_tag}${file_localversion}" fi # Otherwise, default to the annotated tag derived from KERNELVERSION. - if [ -z "${desc}" ]; then - tag="${version_tag}" - desc=$(git describe --match=$tag 2>/dev/null) + if [ -z "${count}" ]; then + try_tag "${version_tag}" fi - # If we are at the tagged commit, we ignore it because the version is - # well-defined. - if [ "${tag}" != "${desc}" ]; then + # If we are at the tagged commit, we ignore it because the + # version is well-defined. If none of the attempted tags exist + # or were usable, $count is still empty. + if [ -z "${count}" ] || [ "${count}" -gt 0 ]; then # If only the short version is requested, don't bother # running further git commands
@@ -95,14 +116,15 @@ scm_version() echo "+" return fi + # If we are past the tagged commit, we pretty print it. # (like 6.1.0-14595-g292a089d78d3) - if [ -n "${desc}" ]; then - echo "${desc}" | awk -F- '{printf("-%05d", $(NF-1))}' + if [ -n "${count}" ]; then + printf "%s%05d" "-" "${count}" fi # Add -g and exactly 12 hex chars. - printf '%s%s' -g "$(echo $head | cut -c1-12)" + printf '%s%.12s' -g "$head" fi if ${no_dirty}; then
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 315/356 io_uring/tctx: work around xa_store() allocation error issue
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit 7eb75ce7527129d7f1fee6951566af409a37a1c4 ]
syzbot triggered the following WARN_ON:
WARNING: CPU: 0 PID: 16 at io_uring/tctx.c:51 __io_uring_free+0xfa/0x140 io_uring/tctx.c:51
which is the
WARN_ON_ONCE(!xa_empty(&tctx->xa));
sanity check in __io_uring_free() when a io_uring_task is going through its final put. The syzbot test case includes injecting memory allocation failures, and it very much looks like xa_store() can fail one of its memory allocations and end up with ->head being non-NULL even though no entries exist in the xarray.
Until this issue gets sorted out, work around it by attempting to iterate entries in our xarray, and WARN_ON_ONCE() if one is found.
--- io_uring/tctx.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
io_uring/tctx.c +12 -1
@@ -47,8 +47,19 @@ static struct io_wq *io_init_wq_offload(struct io_ring_ctx *ctx,void __io_uring_free (struct task_struct *tsk) {struct io_uring_task *tctx = tsk->io_uring; +struct io_tctx_node *node; +unsigned long index; -WARN_ON_ONCE (!xa_empty (&tctx->xa)); +/* +* Fault injection forcing allocation errors in the xa_store() path +* can lead to xa_empty() returning false, even though no actual +* node is stored in the xarray. Until that gets sorted out, attempt +* an iteration here and warn if any entries are found. +*/ +xa_for_each (&tctx->xa, index, node) { +WARN_ON_ONCE (1 ); +break ; + }WARN_ON_ONCE (tctx->io_wq);WARN_ON_ONCE (tctx->cached_refs);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 316/356 sched/numa: Fix mm numa_scan_seq based unconditional scan
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raghavendra K T <[email protected]>
[ Upstream commit 84db47ca7146d7bd00eb5cf2b93989a971c84650 ]
Since commit fc137c0ddab2 ("sched/numa: enhance vma scanning logic")
NUMA Balancing allows updating PTEs to trap NUMA hinting faults if the task had previously accessed VMA. However unconditional scan of VMAs are allowed during initial phase of VMA creation until process's mm numa_scan_seq reaches 2 even though current task had not accessed VMA.
Rationale:
- Without initial scan subsequent PTE update may never happen.
- Give fair opportunity to all the VMAs to be scanned and subsequently
understand the access pattern of all the VMAs.
But it has a corner case where, if a VMA is created after some time, process's mm numa_scan_seq could be already greater than 2.
For e.g., values of mm numa_scan_seq when VMAs are created by running mmtest autonuma benchmark briefly looks like:
start_seq=0 : 459
start_seq=2 : 138
start_seq=3 : 144
start_seq=4 : 8
start_seq=8 : 1
start_seq=9 : 1
This results in no unconditional PTE updates for those VMAs created after some time.
Fix:
- Note down the initial value of mm numa_scan_seq in per VMA start_seq.
- Allow unconditional scan till start_seq + 2.
Result:
SUT: AMD EPYC Milan with 2 NUMA nodes 256 cpus. base kernel: upstream 6.6-rc6 with Mels patches [1] applied.
kernbench
========== base patched %gain
Amean elsp-128 165.09 ( 0.00%) 164.78 * 0.19%*
Duration User 41404.28 41375.08
Duration System 9862.22 9768.48
Duration Elapsed 519.87 518.72
Ops NUMA PTE updates 1041416.00 831536.00 Ops NUMA hint faults 263296.00 220966.00 Ops NUMA pages migrated 258021.00 212769.00
Ops AutoNUMA cost 1328.67 1114.69
autonumabench
NUMA01_THREADLOCAL
==================
Amean elsp-NUMA01_THREADLOCAL 81.79 (0.00%) 67.74 * 17.18%*
Duration User 54832.73 47379.67
Duration System 75.00 185.75
Duration Elapsed 576.72 476.09
Ops NUMA PTE updates 394429.00 11121044.00
Ops NUMA hint faults 1001.00 8906404.00
Ops NUMA pages migrated 288.00 2998694.00
Ops AutoNUMA cost 7.77 44666.84
Stable-dep-of: 5f1b64e9a9b7 ("sched/numa: fix memory leak due to the overwritten vma->numab_state")
--- include/linux/mm_types.h | 3 +++ kernel/sched/fair.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-)
include/linux/mm_types.h +3 -0
@@ -576,6 +576,9 @@ struct vma_numab_state {*/ unsigned long pids_active[2 ]; +/* MM scan sequence ID when scan first started after VMA creation */ +int start_scan_seq; +/* * MM scan sequence ID when the VMA was last completely scanned. * A VMA is not eligible for scanning if prev_scan_seq == numa_scan_seq
kernel/sched/fair.c +3 -1
@@ -3197,7 +3197,7 @@ static bool vma_is_accessed(struct mm_struct *mm, struct vm_area_struct *vma)* This is also done to avoid any side effect of task scanning * amplifying the unfairness of disjoint set of VMAs' access. */ -if (READ_ONCE (current->mm->numa_scan_seq) <2 ) +if ((READ_ONCE (current->mm->numa_scan_seq) - vma->numab_state->start_scan_seq) <2 )return true; pids = vma->numab_state->pids_active[0 ] | vma->numab_state->pids_active[1 ];
@@ -3349,6 +3349,8 @@ static void task_numa_work(struct callback_head *work)if (!vma->numab_state)continue ; + vma->numab_state->start_scan_seq = mm->numa_scan_seq; + vma->numab_state->next_scan = now +msecs_to_jiffies (sysctl_numa_balancing_scan_delay);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 317/356 sched/numa: fix memory leak due to the overwritten vma->numab_state
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Huang <[email protected]>
[ Upstream commit 5f1b64e9a9b7ee9cfd32c6b2fab796e29bfed075 ]
[Problem Description]
When running the hackbench program of LTP, the following memory leak is reported by kmemleak.
# /opt/ltp/testcases/bin/hackbench 20 thread 1000 Running with 20*40 (== 800) tasks.
# dmesg | grep kmemleak ... kmemleak: 480 new suspected memory leaks (see /sys/kernel/debug/kmemleak) kmemleak: 665 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
# cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff888cd8ca2c40 (size 64):
comm "hackbench", pid 17142, jiffies 4299780315
hex dump (first 32 bytes):
ac 74 49 00 01 00 00 00 4c 84 49 00 01 00 00 00 .tI.....L.I.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc bff18fd4):
[<ffffffff81419a89>] __kmalloc_cache_noprof+0x2f9/0x3f0
[<ffffffff8113f715>] task_numa_work+0x725/0xa00
[<ffffffff8110f878>] task_work_run+0x58/0x90
[<ffffffff81ddd9f8>] syscall_exit_to_user_mode+0x1c8/0x1e0
[<ffffffff81dd78d5>] do_syscall_64+0x85/0x150
[<ffffffff81e0012b>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
...This issue can be consistently reproduced on three different servers:
* a 448-core server
* a 256-core server
* a 192-core server
[Root Cause]
Since multiple threads are created by the hackbench program (along with the command argument 'thread'), a shared vma might be accessed by two or more cores simultaneously. When two or more cores observe that vma->numab_state is NULL at the same time, vma->numab_state will be overwritten.
Although current code ensures that only one thread scans the VMAs in a single 'numa_scan_period', there might be a chance for another thread to enter in the next 'numa_scan_period' while we have not gotten till numab_state allocation [1].
Note that the command /opt/ltp/testcases/bin/hackbench 50 process 1000 cannot the reproduce the issue. It is verified with 200+ test runs.
[Solution]
Use the cmpxchg atomic operation to ensure that only one thread executes the vma->numab_state assignment.
[1] https://lore.kernel.org/lkml/[email protected]/
--- kernel/sched/fair.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
kernel/sched/fair.c +9 -3
@@ -3344,10 +3344,16 @@ static void task_numa_work(struct callback_head *work)/* Initialise new per-VMA NUMAB state. */ if (!vma->numab_state) { - vma->numab_state =kzalloc (sizeof (struct vma_numab_state ), -GFP_KERNEL ); -if (!vma->numab_state) +struct vma_numab_state *ptr; + + ptr =kzalloc (sizeof (*ptr),GFP_KERNEL ); +if (!ptr) +continue ; + +if (cmpxchg (&vma->numab_state,NULL , ptr)) { +kfree (ptr);continue ; + } vma->numab_state->start_scan_seq = mm->numa_scan_seq;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 318/356 mempolicy: fix migrate_pages(2) syscall return nr_failed
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugh Dickins <[email protected]>
[ Upstream commit 1cb5d11a370f661c5d0d888bb0cfc2cdc5791382 ]
"man 2 migrate_pages" says "On success migrate_pages() returns the number of pages that could not be moved". Although 5.3 and 5.4 commits fixed mbind(MPOL_MF_STRICT|MPOL_MF_MOVE*) to fail with EIO when not all pages could be moved (because some could not be isolated for migration), migrate_pages(2) was left still reporting only those pages failing at the migration stage, forgetting those failing at the earlier isolation stage.
Fix that by accumulating a long nr_failed count in struct queue_pages, returned by queue_pages_range() when it's not returning an error, for adding on to the nr_failed count from migrate_pages() in mm/migrate.c. A count of pages? It's more a count of folios, but changing it to pages would entail more work (also in mm/migrate.c): does not seem justified.
queue_pages_range() itself should only return -EIO in the "strictly unmovable" case (STRICT without any MOVEs): in that case it's best to break out as soon as nr_failed gets set; but otherwise it should continue to isolate pages for MOVing even when nr_failed - as the mbind(2) manpage promises.
There's a case when nr_failed should be incremented when it was missed:queue_folios_pte_range() and queue_folios_hugetlb() count the transient migration entries, like queue_folios_pmd() already did. And there's a case when nr_failed should not be incremented when it would have been: in meeting later PTEs of the same large folio, which can only be isolated
once: fixed by recording the current large folio in struct queue_pages.
Clean up the affected functions, fixing or updating many comments. Bool migrate_folio_add(), without -EIO: true if adding, or if skipping shared (but its arguable folio_estimated_sharers() heuristic left unchanged). Use MPOL_MF_WRLOCK flag to queue_pages_range(), instead of bool lock_vma. Use explicit STRICT|MOVE* flags where queue_pages_test_walk() checks for skipping, instead of hiding them behind MPOL_MF_VALID.
Stable-dep-of: 091c1dd2d4df ("mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM")
--- mm/mempolicy.c | 338 +++++++++++++++++++++++-------------------------- 1 file changed, 159 insertions(+), 179 deletions(-)
mm/mempolicy.c +159 -179
@@ -111,7 +111,8 @@/* Internal flags */ #define MPOL_MF_DISCONTIG_OK (MPOL_MF_INTERNAL << 0)/* Skip checks for continuous vmas */ -#define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1)/* Invert check for nodemask */ +#define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1)/* Invert check for nodemask */ +#define MPOL_MF_WRLOCK (MPOL_MF_INTERNAL << 2)/* Write-lock walked vmas */ static struct kmem_cache *policy_cache;static struct kmem_cache *sn_cache;
@@ -420,9 +421,19 @@ static const struct mempolicy_operations mpol_ops[MPOL_MAX] = { }, }; -static int migrate_folio_add (struct folio *folio,struct list_head *foliolist, +static bool migrate_folio_add (struct folio *folio,struct list_head *foliolist,unsigned long flags); +static bool strictly_unmovable (unsigned long flags) +{ +/* +* STRICT without MOVE flags lets do_mbind() fail immediately with -EIO +* if any misplaced page is found. +*/ +return (flags & (MPOL_MF_STRICT |MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) == +MPOL_MF_STRICT ; +} +struct queue_pages {struct list_head *pagelist;unsigned long flags;
@@ -430,7 +441,8 @@ struct queue_pages {unsigned long start;unsigned long end;struct vm_area_struct *first; -bool has_unmovable; +struct folio *large;/* note last large folio encountered */ +long nr_failed;/* could not be isolated at this time */ };/*
@@ -448,61 +460,37 @@ static inline bool queue_folio_required(struct folio *folio,return node_isset (nid, *qp->nmask) == !(flags &MPOL_MF_INVERT ); } -/* -* queue_folios_pmd() has three possible return values: -* 0 - folios are placed on the right node or queued successfully, or -* special page is met, i.e. zero page, or unmovable page is found -* but continue walking (indicated by queue_pages.has_unmovable). -* -EIO - is migration entry or only MPOL_MF_STRICT was specified and an -* existing folio was already on a node that does not follow the -* policy. -*/ -static int queue_folios_pmd (pmd_t *pmd,spinlock_t *ptl,unsigned long addr, -unsigned long end,struct mm_walk *walk) -__releases (ptl) +static void queue_folios_pmd (pmd_t *pmd,struct mm_walk *walk) { -int ret =0 ;struct folio *folio;struct queue_pages *qp = walk->private; -unsigned long flags;if (unlikely (is_pmd_migration_entry (*pmd))) { - ret = -EIO ; - goto unlock; + qp->nr_failed++; +return ; } folio =pfn_folio (pmd_pfn (*pmd));if (is_huge_zero_page (&folio->page)) { walk->action =ACTION_CONTINUE ; - goto unlock; +return ; }if (!queue_folio_required (folio, qp)) - goto unlock; - - flags = qp->flags; -/* go to folio migration */ -if (flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) { -if (!vma_migratable (walk->vma) || -migrate_folio_add (folio, qp->pagelist, flags)) { - qp->has_unmovable = true; - goto unlock; - } - }else - ret = -EIO ; -unlock: -spin_unlock (ptl); -return ret; +return ; +if (!(qp->flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) || + !vma_migratable (walk->vma) || + !migrate_folio_add (folio, qp->pagelist, qp->flags)) + qp->nr_failed++; }/* -* Scan through pages checking if pages follow certain conditions, -* and move them to the pagelist if they do. +* Scan through folios, checking if they satisfy the required conditions, +* moving them from LRU to local pagelist for migration if they do (or not). * -* queue_folios_pte_range() has three possible return values: -* 0 - folios are placed on the right node or queued successfully, or -* special page is met, i.e. zero page, or unmovable page is found -* but continue walking (indicated by queue_pages.has_unmovable). -* -EIO - only MPOL_MF_STRICT was specified and an existing folio was already -* on a node that does not follow the policy. +* queue_folios_pte_range() has two possible return values: +* 0 - continue walking to scan for more, even if an existing folio on the +* wrong node could not be isolated and queued for migration. +* -EIO - only MPOL_MF_STRICT was specified, without MPOL_MF_MOVE or ..._ALL, +* and an existing folio was on a node that does not follow the policy. */ static int queue_folios_pte_range (pmd_t *pmd,unsigned long addr,unsigned long end,struct mm_walk *walk)
@@ -516,8 +504,11 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr,spinlock_t *ptl; ptl =pmd_trans_huge_lock (pmd, vma); -if (ptl) -return queue_folios_pmd (pmd, ptl, addr, end, walk); +if (ptl) { +queue_folios_pmd (pmd, walk); +spin_unlock (ptl); + goto out; + } mapped_pte = pte =pte_offset_map_lock (walk->mm, pmd, addr, &ptl);if (!pte) {
@@ -526,8 +517,13 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, }for (; addr != end; pte++, addr +=PAGE_SIZE ) { ptent =ptep_get (pte); -if (!pte_present (ptent)) +if (pte_none (ptent))continue ; +if (!pte_present (ptent)) { +if (is_migration_entry (pte_to_swp_entry (ptent))) + qp->nr_failed++; +continue ; + } folio =vm_normal_folio (vma, addr, ptent);if (!folio ||folio_is_zone_device (folio))continue ;
@@ -539,95 +535,87 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr,continue ;if (!queue_folio_required (folio, qp))continue ; -if (flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) { -/* -* MPOL_MF_STRICT must be specified if we get here. -* Continue walking vmas due to MPOL_MF_MOVE* flags. -*/ -if (!vma_migratable (vma)) - qp->has_unmovable = true; - +if (folio_test_large (folio)) {/* -* Do not abort immediately since there may be -* temporary off LRU pages in the range. Still -* need migrate other LRU pages. +* A large folio can only be isolated from LRU once, +* but may be mapped by many PTEs (and Copy-On-Write may +* intersperse PTEs of other, order 0, folios). This is +* a common case, so don't mistake it for failure (but +* there can be other cases of multi-mapped pages which +* this quick check does not help to filter out - and a +* search of the pagelist might grow to be prohibitive). +* +* migrate_pages(&pagelist) returns nr_failed folios, so +* check "large" now so that queue_pages_range() returns +* a comparable nr_failed folios. This does imply that +* if folio could not be isolated for some racy reason +* at its first PTE, later PTEs will not give it another +* chance of isolation; but keeps the accounting simple. */ -if (migrate_folio_add (folio, qp->pagelist, flags)) - qp->has_unmovable = true; - }else -break ; +if (folio == qp->large) +continue ; + qp->large = folio; + } +if (!(flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) || + !vma_migratable (vma) || + !migrate_folio_add (folio, qp->pagelist, flags)) { + qp->nr_failed++; +if (strictly_unmovable (flags)) +break ; + } }pte_unmap_unlock (mapped_pte, ptl);cond_resched (); - -return addr != end ? -EIO :0 ; +out: +if (qp->nr_failed &&strictly_unmovable (flags)) +return -EIO ; +return 0 ; }static int queue_folios_hugetlb (pte_t *pte,unsigned long hmask,unsigned long addr,unsigned long end,struct mm_walk *walk) { -int ret =0 ;#ifdef CONFIG_HUGETLB_PAGE struct queue_pages *qp = walk->private; -unsigned long flags = (qp->flags &MPOL_MF_VALID ); +unsigned long flags = qp->flags;struct folio *folio;spinlock_t *ptl;pte_t entry; ptl =huge_pte_lock (hstate_vma (walk->vma), walk->mm, pte); entry =huge_ptep_get (pte); -if (!pte_present (entry)) +if (!pte_present (entry)) { +if (unlikely (is_hugetlb_entry_migration (entry))) + qp->nr_failed++; goto unlock; + } folio =pfn_folio (pte_pfn (entry));if (!queue_folio_required (folio, qp)) goto unlock; - -if (flags ==MPOL_MF_STRICT ) { -/* -* STRICT alone means only detecting misplaced folio and no -* need to further check other vma. -*/ - ret = -EIO ; +if (!(flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) || + !vma_migratable (walk->vma)) { + qp->nr_failed++; goto unlock; } - -if (!vma_migratable (walk->vma)) { -/* -* Must be STRICT with MOVE*, otherwise .test_walk() have -* stopped walking current vma. -* Detecting misplaced folio but allow migrating folios which -* have been queued. -*/ - qp->has_unmovable = true; - goto unlock; - } -/* -* With MPOL_MF_MOVE, we try to migrate only unshared folios. If it -* is shared it is likely not worth migrating. +* Unless MPOL_MF_MOVE_ALL, we try to avoid migrating a shared folio. +* Choosing not to migrate a shared folio is not counted as a failure. * * To check if the folio is shared, ideally we want to make sure * every page is mapped to the same process. Doing that is very -* expensive, so check the estimated mapcount of the folio instead. +* expensive, so check the estimated sharers of the folio instead. */ -if (flags & (MPOL_MF_MOVE_ALL ) || - (flags &MPOL_MF_MOVE &&folio_estimated_sharers (folio) ==1 && - !hugetlb_pmd_shared (pte))) { -if (!isolate_hugetlb (folio, qp->pagelist) && - (flags &MPOL_MF_STRICT )) -/* -* Failed to isolate folio but allow migrating pages -* which have been queued. -*/ - qp->has_unmovable = true; - } +if ((flags &MPOL_MF_MOVE_ALL ) || + (folio_estimated_sharers (folio) ==1 && !hugetlb_pmd_shared (pte))) +if (!isolate_hugetlb (folio, qp->pagelist)) + qp->nr_failed++; unlock:spin_unlock (ptl); -#else -BUG (); +if (qp->nr_failed &&strictly_unmovable (flags)) +return -EIO ;#endif -return ret; +return 0 ; }#ifdef CONFIG_NUMA_BALANCING
@@ -708,8 +696,11 @@ static int queue_pages_test_walk(unsigned long start, unsigned long end,return 1 ; } -/* queue pages from current vma */ -if (flags &MPOL_MF_VALID ) +/* +* Check page nodes, and queue pages to move, in the current vma. +* But if no moving, and no strict checking, the scan can be skipped. +*/ +if (flags & (MPOL_MF_STRICT |MPOL_MF_MOVE |MPOL_MF_MOVE_ALL ))return 0 ;return 1 ; }
@@ -731,22 +722,21 @@ static const struct mm_walk_ops queue_pages_lock_vma_walk_ops = {/* * Walk through page tables and collect pages to be migrated. * -* If pages found in a given range are on a set of nodes (determined by -* @nodes and @flags,) it's isolated and queued to the pagelist which is -* passed via @private. +* If pages found in a given range are not on the required set of @nodes, +* and migration is allowed, they are isolated and queued to @pagelist. * -* queue_pages_range() has three possible return values: -* 1 - there is unmovable page, but MPOL_MF_MOVE* & MPOL_MF_STRICT were -* specified. -* 0 - queue pages successfully or no misplaced page. -* errno - i.e. misplaced pages with MPOL_MF_STRICT specified (-EIO) or -* memory range specified by nodemask and maxnode points outside -* your accessible address space (-EFAULT) +* queue_pages_range() may return: +* 0 - all pages already on the right node, or successfully queued for moving +* (or neither strict checking nor moving requested: only range checking). +* >0 - this number of misplaced folios could not be queued for moving +* (a hugetlbfs page or a transparent huge page being counted as 1). +* -EIO - a misplaced page found, when MPOL_MF_STRICT specified without MOVEs. +* -EFAULT - a hole in the memory range, when MPOL_MF_DISCONTIG_OK unspecified. */ -static int +static long queue_pages_range (struct mm_struct *mm,unsigned long start,unsigned long end,nodemask_t *nodes,unsigned long flags, -struct list_head *pagelist,bool lock_vma) +struct list_head *pagelist) {int err;struct queue_pages qp = {
@@ -756,20 +746,17 @@ queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end, .start = start, .end = end, .first = NULL, - .has_unmovable = false, }; -const struct mm_walk_ops *ops = lock_vma ? +const struct mm_walk_ops *ops = (flags &MPOL_MF_WRLOCK ) ? &queue_pages_lock_vma_walk_ops : &queue_pages_walk_ops; err =walk_page_range (mm, start, end, ops, &qp); -if (qp.has_unmovable) - err =1 ;if (!qp.first)/* whole range in hole */ err = -EFAULT ; -return err; +return err ? : qp.nr_failed; }/*
@@ -1032,16 +1019,16 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, }#ifdef CONFIG_MIGRATION -static int migrate_folio_add (struct folio *folio,struct list_head *foliolist, +static bool migrate_folio_add (struct folio *folio,struct list_head *foliolist,unsigned long flags) {/* -* We try to migrate only unshared folios. If it is shared it -* is likely not worth migrating. +* Unless MPOL_MF_MOVE_ALL, we try to avoid migrating a shared folio. +* Choosing not to migrate a shared folio is not counted as a failure. * * To check if the folio is shared, ideally we want to make sure * every page is mapped to the same process. Doing that is very -* expensive, so check the estimated mapcount of the folio instead. +* expensive, so check the estimated sharers of the folio instead. */ if ((flags &MPOL_MF_MOVE_ALL ) ||folio_estimated_sharers (folio) ==1 ) {if (folio_isolate_lru (folio)) {
@@ -1049,32 +1036,31 @@ static int migrate_folio_add(struct folio *folio, struct list_head *foliolist,node_stat_mod_folio (folio,NR_ISOLATED_ANON +folio_is_file_lru (folio),folio_nr_pages (folio)); - }else if (flags &MPOL_MF_STRICT ) { + }else {/* * Non-movable folio may reach here. And, there may be * temporary off LRU folios or non-LRU movable folios. * Treat them as unmovable folios since they can't be -* isolated, so they can't be moved at the moment. It -* should return -EIO for this case too. +* isolated, so they can't be moved at the moment. */ -return -EIO ; +return false; } } - -return 0 ; +return true; }/* * Migrate pages from one node to a target node. * Returns error or the number of pages not migrated. */ -static int migrate_to_node (struct mm_struct *mm,int source,int dest, -int flags) +static long migrate_to_node (struct mm_struct *mm,int source,int dest, +int flags) {nodemask_t nmask;struct vm_area_struct *vma;LIST_HEAD (pagelist); -int err =0 ; +long nr_failed; +long err =0 ;struct migration_target_control mtc = { .nid = dest, .gfp_mask = GFP_HIGHUSER_MOVABLE | __GFP_THISNODE,
@@ -1083,23 +1069,27 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,nodes_clear (nmask);node_set (source, nmask); +VM_BUG_ON (!(flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL ))); + vma =find_vma (mm,0 ); +/* -* This does not "check" the range but isolates all pages that +* This does not migrate the range, but isolates all pages that * need migration. Between passing in the full user address -* space range and MPOL_MF_DISCONTIG_OK, this call can not fail. +* space range and MPOL_MF_DISCONTIG_OK, this call cannot fail, +* but passes back the count of pages which could not be isolated. */ - vma =find_vma (mm,0 ); -VM_BUG_ON (!(flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL ))); -queue_pages_range (mm, vma->vm_start, mm->task_size, &nmask, - flags |MPOL_MF_DISCONTIG_OK , &pagelist, false); + nr_failed =queue_pages_range (mm, vma->vm_start, mm->task_size, &nmask, + flags |MPOL_MF_DISCONTIG_OK , &pagelist);if (!list_empty (&pagelist)) { err =migrate_pages (&pagelist, alloc_migration_target,NULL , - (unsigned long )&mtc,MIGRATE_SYNC ,MR_SYSCALL ,NULL ); + (unsigned long )&mtc,MIGRATE_SYNC ,MR_SYSCALL ,NULL );if (err)putback_movable_pages (&pagelist); } +if (err >=0 ) + err += nr_failed;return err; }
@@ -1112,8 +1102,8 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,int do_migrate_pages (struct mm_struct *mm,const nodemask_t *from,const nodemask_t *to,int flags) { -int busy =0 ; -int err =0 ; +long nr_failed =0 ; +long err =0 ;nodemask_t tmp;lru_cache_disable ();
@@ -1195,7 +1185,7 @@ int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from,node_clear (source, tmp); err =migrate_to_node (mm, source, dest, flags);if (err >0 ) - busy += err; + nr_failed += err;if (err <0 )break ; }
@@ -1204,8 +1194,7 @@ int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from,lru_cache_enable ();if (err <0 )return err; -return busy; - +return (nr_failed <INT_MAX ) ? nr_failed :INT_MAX ; }/*
@@ -1244,10 +1233,10 @@ static struct folio *new_folio(struct folio *src, unsigned long start) }#else -static int migrate_folio_add (struct folio *folio,struct list_head *foliolist, +static bool migrate_folio_add (struct folio *folio,struct list_head *foliolist,unsigned long flags) { -return -EIO ; +return false; } int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from,
@@ -1271,8 +1260,8 @@ static long do_mbind(unsigned long start, unsigned long len,struct vma_iterator vmi;struct mempolicy *new;unsigned long end; -int err; -int ret; +long err; +long nr_failed;LIST_HEAD (pagelist);if (flags & ~(unsigned long )MPOL_MF_VALID )
@@ -1312,10 +1301,8 @@ static long do_mbind(unsigned long start, unsigned long len, start, start + len, mode, mode_flags, nmask ? nodes_addr(*nmask)[0] : NUMA_NO_NODE); -if (flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) { - +if (flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL ))lru_cache_disable (); - } {NODEMASK_SCRATCH (scratch);if (scratch) {
@@ -1331,44 +1318,37 @@ static long do_mbind(unsigned long start, unsigned long len, goto mpol_out;/* -* Lock the VMAs before scanning for pages to migrate, to ensure we don't -* miss a concurrently inserted page. +* Lock the VMAs before scanning for pages to migrate, +* to ensure we don't miss a concurrently inserted page. */ - ret =queue_pages_range (mm, start, end, nmask, - flags |MPOL_MF_INVERT , &pagelist, true); + nr_failed =queue_pages_range (mm, start, end, nmask, + flags |MPOL_MF_INVERT |MPOL_MF_WRLOCK , &pagelist); -if (ret <0 ) { - err = ret; - goto up_out; - } - -vma_iter_init (&vmi, mm, start); - prev =vma_prev (&vmi); -for_each_vma_range (vmi, vma, end) { - err =mbind_range (&vmi, vma, &prev, start, end, new); -if (err) -break ; +if (nr_failed <0 ) { + err = nr_failed; + }else { +vma_iter_init (&vmi, mm, start); + prev =vma_prev (&vmi); +for_each_vma_range (vmi, vma, end) { + err =mbind_range (&vmi, vma, &prev, start, end, new); +if (err) +break ; + } }if (!err) { -int nr_failed =0 ; -if (!list_empty (&pagelist)) {WARN_ON_ONCE (flags &MPOL_MF_LAZY ); - nr_failed =migrate_pages (&pagelist, new_folio,NULL , + nr_failed |=migrate_pages (&pagelist, new_folio,NULL , start,MIGRATE_SYNC ,MR_MEMPOLICY_MBIND ,NULL ); -if (nr_failed) -putback_movable_pages (&pagelist); } - -if (((ret >0 ) || nr_failed) && (flags &MPOL_MF_STRICT )) +if (nr_failed && (flags &MPOL_MF_STRICT )) err = -EIO ; - }else { -up_out: -if (!list_empty (&pagelist)) -putback_movable_pages (&pagelist); } +if (!list_empty (&pagelist)) +putback_movable_pages (&pagelist); +mmap_write_unlock (mm); mpol_out:mpol_put (new);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 319/356 mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit 091c1dd2d4df6edd1beebe0e5863d4034ade9572 ]
We currently assume that there is at least one VMA in a MM, which isn't true.
So we might end up having find_vma() return NULL, to then de-reference NULL. So properly handle find_vma() returning NULL.
This fixes the report:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 UID: 0 PID: 6021 Comm: syz-executor284 Not tainted 6.12.0-rc7-syzkaller-00187-gf868cd251776 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/30/2024 RIP: 0010:migrate_to_node mm/mempolicy.c:1090 [inline] RIP: 0010:do_migrate_pages+0x403/0x6f0 mm/mempolicy.c:1194 Code: ... RSP: 0018:ffffc9000375fd08 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffc9000375fd78 RCX: 0000000000000000 RDX: ffff88807e171300 RSI: dffffc0000000000 RDI: ffff88803390c044 RBP: ffff88807e171428 R08: 0000000000000014 R09: fffffbfff2039ef1 R10: ffffffff901cf78f R11: 0000000000000000 R12: 0000000000000003 R13: ffffc9000375fe90 R14: ffffc9000375fe98 R15: ffffc9000375fdf8 FS: 00005555919e1380(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005555919e1ca8 CR3: 000000007f12a000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> kernel_migrate_pages+0x5b2/0x750 mm/mempolicy.c:1709 __do_sys_migrate_pages mm/mempolicy.c:1727 [inline] __se_sys_migrate_pages mm/mempolicy.c:1723 [inline] __x64_sys_migrate_pages+0x96/0x100 mm/mempolicy.c:1723 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- mm/mempolicy.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/mempolicy.c +4 -0
@@ -1071,6 +1071,10 @@ static long migrate_to_node(struct mm_struct *mm, int source, int dest,VM_BUG_ON (!(flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL ))); vma =find_vma (mm,0 ); +if (unlikely (!vma)) { +mmap_read_unlock (mm); +return 0 ; + }/* * This does not migrate the range, but isolates all pages that
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 320/356 sched/core: Remove the unnecessary need_resched() check in nohz_csd_func()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: K Prateek Nayak <[email protected]>
[ Upstream commit ea9cffc0a154124821531991d5afdd7e8b20d7aa ]
The need_resched() check currently in nohz_csd_func() can be tracked to have been added in scheduler_ipi() back in 2011 via commit ca38062e57e9 ("sched: Use resched IPI to kick off the nohz idle balance")
Since then, it has travelled quite a bit but it seems like an idle_cpu() check currently is sufficient to detect the need to bail out from an idle load balancing. To justify this removal, consider all the following case where an idle load balancing could race with a task wakeup:
o Since commit f3dd3f674555b ("sched: Remove the limitation of WF_ON_CPU on wakelist if wakee cpu is idle") a target perceived to be idle (target_rq->nr_running == 0) will return true for ttwu_queue_cond(target) which will offload the task wakeup to the idle target via an IPI.
In all such cases target_rq->ttwu_pending will be set to 1 before queuing the wake function.
If an idle load balance races here, following scenarios are possible:
- The CPU is not in TIF_POLLING_NRFLAG mode in which case an actual IPI is sent to the CPU to wake it out of idle. If the nohz_csd_func() queues before sched_ttwu_pending(), the idle load balance will bail out since idle_cpu(target) returns 0 since target_rq->ttwu_pending is 1. If the nohz_csd_func() is queued after sched_ttwu_pending() it should see rq->nr_running to be non-zero and bail out of idle load balancing.
- The CPU is in TIF_POLLING_NRFLAG mode and instead of an actual IPI, the sender will simply set TIF_NEED_RESCHED for the target to put it out of idle and flush_smp_call_function_queue() in do_idle() will execute the call function. Depending on the ordering of the queuing of nohz_csd_func() and sched_ttwu_pending(), the idle_cpu() check in nohz_csd_func() should either see target_rq->ttwu_pending = 1 or target_rq->nr_running to be non-zero if there is a genuine task wakeup racing with the idle load balance kick.
o The waker CPU perceives the target CPU to be busy (targer_rq->nr_running != 0) but the CPU is in fact going idle and due to a series of unfortunate events, the system reaches a case where the waker CPU decides to perform the wakeup by itself in ttwu_queue() on the target CPU but target is concurrently selected for idle load balance (XXX: Can this happen? I'm not sure, but we'll consider the mother of all coincidences to estimate the worst case scenario).
ttwu_do_activate() calls enqueue_task() which would increment "rq->nr_running" post which it calls wakeup_preempt() which is responsible for setting TIF_NEED_RESCHED (via a resched IPI or by setting TIF_NEED_RESCHED on a TIF_POLLING_NRFLAG idle CPU) The key thing to note in this case is that rq->nr_running is already non-zero in case of a wakeup before TIF_NEED_RESCHED is set which would lead to idle_cpu() check returning false.
In all cases, it seems that need_resched() check is unnecessary when checking for idle_cpu() first since an impending wakeup racing with idle load balancer will either set the "rq->ttwu_pending" or indicate a newly woken task via "rq->nr_running".
Chasing the reason why this check might have existed in the first place, I came across Peter's suggestion on the fist iteration of Suresh's patch from 2011 [1] where the condition to raise the SCHED_SOFTIRQ was:
sched_ttwu_do_pending(list); if (unlikely((rq->idle == current) && rq->nohz_balance_kick && !need_resched())) raise_softirq_irqoff(SCHED_SOFTIRQ);
Since the condition to raise the SCHED_SOFIRQ was preceded by sched_ttwu_do_pending() (which is equivalent of sched_ttwu_pending()) in the current upstream kernel, the need_resched() check was necessary to catch a newly queued task. Peter suggested modifying it to:
if (idle_cpu() && rq->nohz_balance_kick && !need_resched()) raise_softirq_irqoff(SCHED_SOFTIRQ);
where idle_cpu() seems to have replaced "rq->idle == current" check.
Even back then, the idle_cpu() check would have been sufficient to catch a new task being enqueued. Since commit b2a02fc43a1f ("smp: Optimize send_call_function_single_ipi()") overloads the interpretation of TIF_NEED_RESCHED for TIF_POLLING_NRFLAG idling, remove the need_resched() check in nohz_csd_func() to raise SCHED_SOFTIRQ based on Peter's suggestion.
--- kernel/sched/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/core.c +1 -1
@@ -1181,7 +1181,7 @@ static void nohz_csd_func(void *info)WARN_ON (!(flags &NOHZ_KICK_MASK )); rq->idle_balance =idle_cpu (cpu); -if (rq->idle_balance && !need_resched ()) { +if (rq->idle_balance) { rq->nohz_idle_balance = flags;raise_softirq_irqoff (SCHED_SOFTIRQ ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 321/356 sched/fair: Check idle_cpu() before need_resched() to detect ilb CPU turning busy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: K Prateek Nayak <[email protected]>
[ Upstream commit ff47a0acfcce309cf9e175149c75614491953c8f ]
Commit b2a02fc43a1f ("smp: Optimize send_call_function_single_ipi()") optimizes IPIs to idle CPUs in TIF_POLLING_NRFLAG mode by setting the TIF_NEED_RESCHED flag in idle task's thread info and relying on flush_smp_call_function_queue() in idle exit path to run the call-function. A softirq raised by the call-function is handled shortly after in do_softirq_post_smp_call_flush() but the TIF_NEED_RESCHED flag remains set and is only cleared later when schedule_idle() calls __schedule().
need_resched() check in _nohz_idle_balance() exists to bail out of load balancing if another task has woken up on the CPU currently in-charge of idle load balancing which is being processed in SCHED_SOFTIRQ context. Since the optimization mentioned above overloads the interpretation of TIF_NEED_RESCHED, check for idle_cpu() before going with the existing need_resched() check which can catch a genuine task wakeup on an idle CPU processing SCHED_SOFTIRQ from do_softirq_post_smp_call_flush(), as well as the case where ksoftirqd needs to be preempted as a result of new task wakeup or slice expiry.
In case of PREEMPT_RT or threadirqs, although the idle load balancing may be inhibited in some cases on the ilb CPU, the fact that ksoftirqd is the only fair task going back to sleep will trigger a newidle balance on the CPU which will alleviate some imbalance if it exists if idle balance fails to do so.
--- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/fair.c +1 -1
@@ -12121,7 +12121,7 @@ static void _nohz_idle_balance(struct rq *this_rq, unsigned int flags)* work being done for other CPUs. Next load * balancing owner will pick it up. */ -if (need_resched ()) { +if (!idle_cpu (this_cpu) &&need_resched ()) {if (flags &NOHZ_STATS_KICK ) has_blocked_load = true;if (flags &NOHZ_NEXT_KICK )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 322/356 sched/core: Prevent wakeup of ksoftirqd during idle load balance
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: K Prateek Nayak <[email protected]>
[ Upstream commit e932c4ab38f072ce5894b2851fea8bc5754bb8e5 ]
Scheduler raises a SCHED_SOFTIRQ to trigger a load balancing event on from the IPI handler on the idle CPU. If the SMP function is invoked from an idle CPU via flush_smp_call_function_queue() then the HARD-IRQ flag is not set and raise_softirq_irqoff() needlessly wakes ksoftirqd because soft interrupts are handled before ksoftirqd get on the CPU.
Adding a trace_printk() in nohz_csd_func() at the spot of raising SCHED_SOFTIRQ and enabling trace events for sched_switch, sched_wakeup, and softirq_entry (for SCHED_SOFTIRQ vector alone) helps observing the current behavior:
<idle>-0 [000] dN.1.: nohz_csd_func: Raising SCHED_SOFTIRQ from nohz_csd_func
<idle>-0 [000] dN.4.: sched_wakeup: comm=ksoftirqd/0 pid=16 prio=120 target_cpu=000
<idle>-0 [000] .Ns1.: softirq_entry: vec=7 [action=SCHED]
<idle>-0 [000] .Ns1.: softirq_exit: vec=7 [action=SCHED]
<idle>-0 [000] d..2.: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=16 next_prio=120
ksoftirqd/0-16 [000] d..2.: sched_switch: prev_comm=ksoftirqd/0 prev_pid=16 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
...Use __raise_softirq_irqoff() to raise the softirq. The SMP function call is always invoked on the requested CPU in an interrupt handler. It is guaranteed that soft interrupts are handled at the end.
Following are the observations with the changes when enabling the same set of events:
<idle>-0 [000] dN.1.: nohz_csd_func: Raising SCHED_SOFTIRQ for nohz_idle_balance
<idle>-0 [000] dN.1.: softirq_raise: vec=7 [action=SCHED]
<idle>-0 [000] .Ns1.: softirq_entry: vec=7 [action=SCHED]No unnecessary ksoftirqd wakeups are seen from idle task's context to service the softirq.
--- kernel/sched/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/core.c +1 -1
@@ -1183,7 +1183,7 @@ static void nohz_csd_func(void *info) rq->idle_balance =idle_cpu (cpu);if (rq->idle_balance) { rq->nohz_idle_balance = flags; -raise_softirq_irqoff (SCHED_SOFTIRQ ); +__raise_softirq_irqoff (SCHED_SOFTIRQ ); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 323/356 sched/fair: Rename check_preempt_wakeup() to check_preempt_wakeup_fair()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ingo Molnar <[email protected]>
[ Upstream commit 82845683ca6a15fe8c7912c6264bb0e84ec6f5fb ]
Other scheduling classes already postfix their similar methods with the class name.
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- kernel/sched/fair.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/sched/fair.c +2 -2
@@ -8255,7 +8255,7 @@ static void set_next_buddy(struct sched_entity *se)/* * Preempt the current task with a newly woken task if needed: */ -static void check_preempt_wakeup (struct rq *rq,struct task_struct *p,int wake_flags) +static void check_preempt_wakeup_fair (struct rq *rq,struct task_struct *p,int wake_flags) {struct task_struct *curr = rq->curr;struct sched_entity *se = &curr->se, *pse = &p->se;
@@ -13102,7 +13102,7 @@ DEFINE_SCHED_CLASS(fair) = { .yield_task = yield_task_fair, .yield_to_task = yield_to_task_fair, - .check_preempt_curr = check_preempt_wakeup, + .check_preempt_curr = check_preempt_wakeup_fair, .pick_next_task = __pick_next_task_fair, .put_prev_task = put_prev_task_fair,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 324/356 sched/fair: Rename check_preempt_curr() to wakeup_preempt()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ingo Molnar <[email protected]>
[ Upstream commit e23edc86b09df655bf8963bbcb16647adc787395 ]
The name is a bit opaque - make it clear that this is about wakeup preemption.
Also rename the ->check_preempt_curr() methods similarly.
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- kernel/sched/core.c | 14 +++++++------- kernel/sched/deadline.c | 10 +++++----- kernel/sched/fair.c | 10 +++++----- kernel/sched/idle.c | 4 ++-- kernel/sched/rt.c | 6 +++--- kernel/sched/sched.h | 4 ++-- kernel/sched/stop_task.c | 4 ++-- 7 files changed, 26 insertions(+), 26 deletions(-)
kernel/sched/core.c +7 -7
@@ -2214,10 +2214,10 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p, p->sched_class->prio_changed (rq, p, oldprio); } -void check_preempt_curr (struct rq *rq,struct task_struct *p,int flags) +void wakeup_preempt (struct rq *rq,struct task_struct *p,int flags) {if (p->sched_class == rq->curr->sched_class) - rq->curr->sched_class->check_preempt_curr (rq, p, flags); + rq->curr->sched_class->wakeup_preempt (rq, p, flags);else if (sched_class_above (p->sched_class, rq->curr->sched_class))resched_curr (rq);
@@ -2523,7 +2523,7 @@ static struct rq *move_queued_task(struct rq *rq, struct rq_flags *rf,rq_lock (rq, rf);WARN_ON_ONCE (task_cpu (p) != new_cpu);activate_task (rq, p,0 ); -check_preempt_curr (rq, p,0 ); +wakeup_preempt (rq, p,0 );return rq; }
@@ -3409,7 +3409,7 @@ static void __migrate_swap_task(struct task_struct *p, int cpu)deactivate_task (src_rq, p,0 );set_task_cpu (p, cpu);activate_task (dst_rq, p,0 ); -check_preempt_curr (dst_rq, p,0 ); +wakeup_preempt (dst_rq, p,0 );rq_unpin_lock (dst_rq, &drf);rq_unpin_lock (src_rq, &srf);
@@ -3785,7 +3785,7 @@ ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags, }activate_task (rq, p, en_flags); -check_preempt_curr (rq, p, wake_flags); +wakeup_preempt (rq, p, wake_flags);ttwu_do_wakeup (p);
@@ -3856,7 +3856,7 @@ static int ttwu_runnable(struct task_struct *p, int wake_flags)* it should preempt the task that is current now. */ update_rq_clock (rq); -check_preempt_curr (rq, p, wake_flags); +wakeup_preempt (rq, p, wake_flags); }ttwu_do_wakeup (p); ret =1 ;
@@ -4871,7 +4871,7 @@ void wake_up_new_task(struct task_struct *p)activate_task (rq, p,ENQUEUE_NOCLOCK );trace_sched_wakeup_new (p); -check_preempt_curr (rq, p,WF_FORK ); +wakeup_preempt (rq, p,WF_FORK );#ifdef CONFIG_SMP if (p->sched_class->task_woken) {/*
kernel/sched/deadline.c +5 -5
@@ -763,7 +763,7 @@ static inline void deadline_queue_pull_task(struct rq *rq)static void enqueue_task_dl (struct rq *rq,struct task_struct *p,int flags);static void __dequeue_task_dl (struct rq *rq,struct task_struct *p,int flags); -static void check_preempt_curr_dl (struct rq *rq,struct task_struct *p,int flags); +static void wakeup_preempt_dl (struct rq *rq,struct task_struct *p,int flags);static inline void replenish_dl_new_period (struct sched_dl_entity *dl_se,struct rq *rq)
@@ -1175,7 +1175,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)enqueue_task_dl (rq, p,ENQUEUE_REPLENISH );if (dl_task (rq->curr)) -check_preempt_curr_dl (rq, p,0 ); +wakeup_preempt_dl (rq, p,0 );else resched_curr (rq);
@@ -1939,7 +1939,7 @@ static int balance_dl(struct rq *rq, struct task_struct *p, struct rq_flags *rf)* Only called when both the current and waking task are -deadline * tasks. */ -static void check_preempt_curr_dl (struct rq *rq,struct task_struct *p, +static void wakeup_preempt_dl (struct rq *rq,struct task_struct *p,int flags) {if (dl_entity_preempt (&p->dl, &rq->curr->dl)) {
@@ -2654,7 +2654,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)deadline_queue_push_tasks (rq);#endif if (dl_task (rq->curr)) -check_preempt_curr_dl (rq, p,0 ); +wakeup_preempt_dl (rq, p,0 );else resched_curr (rq); }else {
@@ -2723,7 +2723,7 @@ DEFINE_SCHED_CLASS(dl) = { .dequeue_task = dequeue_task_dl, .yield_task = yield_task_dl, - .check_preempt_curr = check_preempt_curr_dl, + .wakeup_preempt = wakeup_preempt_dl, .pick_next_task = pick_next_task_dl, .put_prev_task = put_prev_task_dl,
kernel/sched/fair.c +5 -5
@@ -8268,7 +8268,7 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int/* * This is possible from callers such as attach_tasks(), in which we -* unconditionally check_preempt_curr() after an enqueue (which may have +* unconditionally wakeup_preempt() after an enqueue (which may have * lead to a throttle). This both saves work and prevents false * next-buddy nomination below. */
@@ -9167,7 +9167,7 @@ static void attach_task(struct rq *rq, struct task_struct *p)WARN_ON_ONCE (task_rq (p) != rq);activate_task (rq, p,ENQUEUE_NOCLOCK ); -check_preempt_curr (rq, p,0 ); +wakeup_preempt (rq, p,0 ); }/*
@@ -12641,7 +12641,7 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio)if (p->prio > oldprio)resched_curr (rq); }else -check_preempt_curr (rq, p,0 ); +wakeup_preempt (rq, p,0 ); }#ifdef CONFIG_FAIR_GROUP_SCHED
@@ -12743,7 +12743,7 @@ static void switched_to_fair(struct rq *rq, struct task_struct *p)if (task_current (rq, p))resched_curr (rq);else -check_preempt_curr (rq, p,0 ); +wakeup_preempt (rq, p,0 ); } }
@@ -13102,7 +13102,7 @@ DEFINE_SCHED_CLASS(fair) = { .yield_task = yield_task_fair, .yield_to_task = yield_to_task_fair, - .check_preempt_curr = check_preempt_wakeup_fair, + .wakeup_preempt = check_preempt_wakeup_fair, .pick_next_task = __pick_next_task_fair, .put_prev_task = put_prev_task_fair,
kernel/sched/idle.c +2 -2
@@ -401,7 +401,7 @@ balance_idle(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)/* * Idle tasks are unconditionally rescheduled: */ -static void check_preempt_curr_idle (struct rq *rq,struct task_struct *p,int flags) +static void wakeup_preempt_idle (struct rq *rq,struct task_struct *p,int flags) {resched_curr (rq); }
@@ -482,7 +482,7 @@ DEFINE_SCHED_CLASS(idle) = {/* dequeue is not valid, we print a debug message there: */ .dequeue_task = dequeue_task_idle, - .check_preempt_curr = check_preempt_curr_idle, + .wakeup_preempt = wakeup_preempt_idle, .pick_next_task = pick_next_task_idle, .put_prev_task = put_prev_task_idle,
kernel/sched/rt.c +3 -3
@@ -957,7 +957,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)/* * When we're idle and a woken (rt) task is -* throttled check_preempt_curr() will set +* throttled wakeup_preempt() will set * skip_update and the time between the wakeup * and this unthrottle will get accounted as * 'runtime'.
@@ -1719,7 +1719,7 @@ static int balance_rt(struct rq *rq, struct task_struct *p, struct rq_flags *rf)/* * Preempt the current task with a newly woken task if needed: */ -static void check_preempt_curr_rt (struct rq *rq,struct task_struct *p,int flags) +static void wakeup_preempt_rt (struct rq *rq,struct task_struct *p,int flags) {if (p->prio < rq->curr->prio) {resched_curr (rq);
@@ -2710,7 +2710,7 @@ DEFINE_SCHED_CLASS(rt) = { .dequeue_task = dequeue_task_rt, .yield_task = yield_task_rt, - .check_preempt_curr = check_preempt_curr_rt, + .wakeup_preempt = wakeup_preempt_rt, .pick_next_task = pick_next_task_rt, .put_prev_task = put_prev_task_rt,
kernel/sched/sched.h +2 -2
@@ -2242,7 +2242,7 @@ struct sched_class {void (*yield_task) (struct rq *rq);bool (*yield_to_task)(struct rq *rq,struct task_struct *p); -void (*check_preempt_curr)(struct rq *rq,struct task_struct *p,int flags); +void (*wakeup_preempt)(struct rq *rq,struct task_struct *p,int flags);struct task_struct *(*pick_next_task)(struct rq *rq);
@@ -2516,7 +2516,7 @@ static inline void sub_nr_running(struct rq *rq, unsigned count)extern void activate_task (struct rq *rq,struct task_struct *p,int flags);extern void deactivate_task (struct rq *rq,struct task_struct *p,int flags); -extern void check_preempt_curr (struct rq *rq,struct task_struct *p,int flags); +extern void wakeup_preempt (struct rq *rq,struct task_struct *p,int flags);#ifdef CONFIG_PREEMPT_RT #define SCHED_NR_MIGRATE_BREAK 8
kernel/sched/stop_task.c +2 -2
@@ -23,7 +23,7 @@ balance_stop(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)#endif /* CONFIG_SMP */ static void -check_preempt_curr_stop (struct rq *rq,struct task_struct *p,int flags) +wakeup_preempt_stop (struct rq *rq,struct task_struct *p,int flags) {/* we're never preempted */ }
@@ -120,7 +120,7 @@ DEFINE_SCHED_CLASS(stop) = { .dequeue_task = dequeue_task_stop, .yield_task = yield_task_stop, - .check_preempt_curr = check_preempt_curr_stop, + .wakeup_preempt = wakeup_preempt_stop, .pick_next_task = pick_next_task_stop, .put_prev_task = put_prev_task_stop,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 325/356 sched/headers: Move struct sched_param out of uapi, to work around glibc/musl breakage
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kir Kolyshkin <[email protected]>
[ Upstream commit d844fe65f0957024c3e1b0bf2a0615246184d9bc ]
Both glibc and musl define 'struct sched_param' in sched.h, while kernel has it in uapi/linux/sched/types.h, making it cumbersome to use sched_getattr(2) or sched_setattr(2) from userspace.
For example, something like this:
#include <sched.h> #include <linux/sched/types.h> struct sched_attr sa;
will result in "error: redefinition of ‘struct sched_param’" (note the code doesn't need sched_param at all -- it needs struct sched_attr plus some stuff from sched.h).
The situation is, glibc is not going to provide a wrapper for sched_{get,set}attr, thus the need to include linux/sched_types.h directly, which leads to the above problem.
Thus, the userspace is left with a few sub-par choices when it wants to use e.g. sched_setattr(2), such as maintaining a copy of struct sched_attr definition, or using some other ugly tricks.
OTOH, 'struct sched_param' is well known, defined in POSIX, and it won't be ever changed (as that would break backward compatibility).
So, while 'struct sched_param' is indeed part of the kernel uapi, exposing it the way it's done now creates an issue, and hiding it (like this patch does) fixes that issue, hopefully without creating another one: common userspace software rely on libc headers, and as for "special" software (like libc), it looks like glibc and musl do not rely on kernel headers for 'struct sched_param' definition (but let's Cc their mailing lists in case it's otherwise).
The alternative to this patch would be to move struct sched_attr to, say, linux/sched.h, or linux/sched/attr.h (the new file).
Oh, and here is the previous attempt to fix the issue:
https://lore.kernel.org/all/[email protected]/
While I support Linus arguments, the issue is still here and needs to be fixed.
[ mingo: Linus is right, this shouldn't be needed - but on the other
hand I agree that this header is not really helpful to user-space as-is. So let's pretend that <uapi/linux/sched/types.h> is only about sched_attr, and call this commit a workaround for user-space breakage that it in reality is ... Also, remove the Fixes tag. ]
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- include/linux/sched.h | 5 ++++- include/uapi/linux/sched/types.h | 4 ---- 2 files changed, 4 insertions(+), 5 deletions(-)
include/linux/sched.h +4 -1
@@ -63,7 +63,6 @@ struct robust_list_head;struct root_domain ;struct rq ;struct sched_attr ; -struct sched_param ;struct seq_file ;struct sighand_struct ;struct signal_struct ;
@@ -370,6 +369,10 @@ extern struct root_domain def_root_domain;extern struct mutex sched_domains_mutex;#endif +struct sched_param { +int sched_priority; +}; +struct sched_info {#ifdef CONFIG_SCHED_INFO /* Cumulative counters: */
include/uapi/linux/sched/types.h +0 -4
@@ -4,10 +4,6 @@#include <linux/types.h> -struct sched_param { -int sched_priority; -}; -#define SCHED_ATTR_SIZE_VER0 48/* sizeof first published struct */ #define SCHED_ATTR_SIZE_VER1 56/* add: util_{min,max} */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 326/356 sched: Unify runtime accounting across classes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 5d69eca542ee17c618f9a55da52191d5e28b435f ]
All classes use sched_entity::exec_start to track runtime and have copies of the exact same code around to compute runtime.
Collapse all that.
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- include/linux/sched.h | 2 +- kernel/sched/deadline.c | 15 +++-------- kernel/sched/fair.c | 57 ++++++++++++++++++++++++++++++---------- kernel/sched/rt.c | 15 +++-------- kernel/sched/sched.h | 12 ++------- kernel/sched/stop_task.c | 13 +-------- 6 files changed, 53 insertions(+), 61 deletions(-)
include/linux/sched.h +1 -1
@@ -523,7 +523,7 @@ struct sched_statistics {u64 block_max;s64 sum_block_runtime; -u64 exec_max; +s64 exec_max;u64 slice_max;u64 nr_migrations_cold;
kernel/sched/deadline.c +3 -12
@@ -1299,9 +1299,8 @@ static void update_curr_dl(struct rq *rq) {struct task_struct *curr = rq->curr;struct sched_dl_entity *dl_se = &curr->dl; -u64 delta_exec, scaled_delta_exec; +s64 delta_exec, scaled_delta_exec;int cpu =cpu_of (rq); -u64 now;if (!dl_task (curr) || !on_dl_rq (dl_se))return ;
@@ -1314,21 +1313,13 @@ static void update_curr_dl(struct rq *rq)* natural solution, but the full ramifications of this * approach need further study. */ - now =rq_clock_task (rq); - delta_exec = now - curr->se.exec_start; -if (unlikely ((s64 )delta_exec <=0 )) { + delta_exec =update_curr_common (rq); +if (unlikely (delta_exec <=0 )) {if (unlikely (dl_se->dl_yielded)) goto throttle;return ; } -schedstat_set (curr->stats.exec_max, -max (curr->stats.exec_max, delta_exec)); - -trace_sched_stat_runtime (curr, delta_exec,0 ); - -update_current_exec_runtime (curr, now, delta_exec); -if (dl_entity_is_special (dl_se))return ;
kernel/sched/fair.c +43 -14
74 lines not on this page · raw message
kernel/sched/rt.c +3 -12
@@ -1050,24 +1050,15 @@ static void update_curr_rt(struct rq *rq) {struct task_struct *curr = rq->curr;struct sched_rt_entity *rt_se = &curr->rt; -u64 delta_exec; -u64 now; +s64 delta_exec;if (curr->sched_class != &rt_sched_class)return ; - now =rq_clock_task (rq); - delta_exec = now - curr->se.exec_start; -if (unlikely ((s64 )delta_exec <=0 )) + delta_exec =update_curr_common (rq); +if (unlikely (delta_exec <=0 ))return ; -schedstat_set (curr->stats.exec_max, -max (curr->stats.exec_max, delta_exec)); - -trace_sched_stat_runtime (curr, delta_exec,0 ); - -update_current_exec_runtime (curr, now, delta_exec); -if (!rt_bandwidth_enabled ())return ;
kernel/sched/sched.h +2 -10
@@ -2231,6 +2231,8 @@ struct affinity_context {unsigned int flags; }; +extern s64 update_curr_common (struct rq *rq); +struct sched_class {#ifdef CONFIG_UCLAMP_TASK
@@ -3283,16 +3285,6 @@ extern int sched_dynamic_mode(const char *str);extern void sched_dynamic_update (int mode);#endif -static inline void update_current_exec_runtime (struct task_struct *curr, -u64 now,u64 delta_exec) -{ - curr->se.sum_exec_runtime += delta_exec; -account_group_exec_runtime (curr, delta_exec); - - curr->se.exec_start = now; -cgroup_account_cputime (curr, delta_exec); -} -#ifdef CONFIG_SCHED_MM_CID #define SCHED_MM_CID_PERIOD_NS (100ULL * 1000000)/* 100ms */
kernel/sched/stop_task.c +1 -12
@@ -70,18 +70,7 @@ static void yield_task_stop(struct rq *rq)static void put_prev_task_stop (struct rq *rq,struct task_struct *prev) { -struct task_struct *curr = rq->curr; -u64 now, delta_exec; - - now =rq_clock_task (rq); - delta_exec = now - curr->se.exec_start; -if (unlikely ((s64 )delta_exec <0 )) - delta_exec =0 ; - -schedstat_set (curr->stats.exec_max, -max (curr->stats.exec_max, delta_exec)); - -update_current_exec_runtime (curr, now, delta_exec); +update_curr_common (rq); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 327/356 sched: Remove vruntime from trace_sched_stat_runtime()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 5fe6ec8f6ab549b6422e41551abb51802bd48bc7 ]
Tracing the runtime delta makes sense, observer can sum over time. Tracing the absolute vruntime makes less sense, inconsistent:
absolute-vs-delta, but also vruntime delta can be computed from runtime delta.
Removing the vruntime thing also makes the two tracepoint sites identical, allowing to unify the code in a later patch.
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- include/trace/events/sched.h | 15 ++++++--------- kernel/sched/fair.c | 5 ++--- 2 files changed, 8 insertions(+), 12 deletions(-)
include/trace/events/sched.h +6 -9
@@ -493,33 +493,30 @@ DEFINE_EVENT_SCHEDSTAT(sched_stat_template, sched_stat_blocked,*/ DECLARE_EVENT_CLASS (sched_stat_runtime, - TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime), + TP_PROTO(struct task_struct *tsk, u64 runtime), -TP_ARGS (tsk,__perf_count (runtime), vruntime), +TP_ARGS (tsk,__perf_count (runtime)),TP_STRUCT__entry ( __array( char, comm, TASK_COMM_LEN ) __field( pid_t, pid )__field ( u64, runtime ) -__field ( u64, vruntime ) ),TP_fast_assign ( memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN); __entry->pid = tsk->pid; __entry->runtime = runtime; - __entry->vruntime = vruntime; ), -TP_printk ("comm=%s pid=%d runtime=%Lu [ns] vruntime=%Lu [ns]" , +TP_printk ("comm=%s pid=%d runtime=%Lu [ns]" , __entry->comm, __entry->pid, - (unsigned long long )__entry->runtime, - (unsigned long long )__entry->vruntime) + (unsigned long long )__entry->runtime) );DEFINE_EVENT (sched_stat_runtime, sched_stat_runtime, - TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime), -TP_ARGS (tsk, runtime, vruntime)); + TP_PROTO(struct task_struct *tsk, u64 runtime), +TP_ARGS (tsk, runtime));/* * Tracepoint for showing priority inheritance modifying a tasks
kernel/sched/fair.c +2 -3
@@ -1185,8 +1185,7 @@ s64 update_curr_common(struct rq *rq)if (unlikely (delta_exec <=0 ))return delta_exec; -trace_sched_stat_runtime (curr, delta_exec,0 ); - +trace_sched_stat_runtime (curr, delta_exec);account_group_exec_runtime (curr, delta_exec);cgroup_account_cputime (curr, delta_exec);
@@ -1215,7 +1214,7 @@ static void update_curr(struct cfs_rq *cfs_rq)if (entity_is_task (curr)) {struct task_struct *curtask =task_of (curr); -trace_sched_stat_runtime (curtask, delta_exec, curr->vruntime); +trace_sched_stat_runtime (curtask, delta_exec);cgroup_account_cputime (curtask, delta_exec);account_group_exec_runtime (curtask, delta_exec); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 328/356 sched: Unify more update_curr*()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit c708a4dc5ab547edc3d6537233ca9e79ea30ce47 ]
Now that trace_sched_stat_runtime() no longer takes a vruntime argument, the task specific bits are identical between update_curr_common() and update_curr().
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- kernel/sched/fair.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
kernel/sched/fair.c +11 -13
@@ -1173,6 +1173,13 @@ static s64 update_curr_se(struct rq *rq, struct sched_entity *curr)return delta_exec; } +static inline void update_curr_task (struct task_struct *p,s64 delta_exec) +{ +trace_sched_stat_runtime (p, delta_exec); +account_group_exec_runtime (p, delta_exec); +cgroup_account_cputime (p, delta_exec); +} +/* * Used by other classes to account runtime. */
@@ -1182,12 +1189,8 @@ s64 update_curr_common(struct rq *rq)s64 delta_exec; delta_exec =update_curr_se (rq, &curr->se); -if (unlikely (delta_exec <=0 )) -return delta_exec; - -trace_sched_stat_runtime (curr, delta_exec); -account_group_exec_runtime (curr, delta_exec); -cgroup_account_cputime (curr, delta_exec); +if (likely (delta_exec >0 )) +update_curr_task (curr, delta_exec);return delta_exec; }
@@ -1211,13 +1214,8 @@ static void update_curr(struct cfs_rq *cfs_rq)update_deadline (cfs_rq, curr);update_min_vruntime (cfs_rq); -if (entity_is_task (curr)) { -struct task_struct *curtask =task_of (curr); - -trace_sched_stat_runtime (curtask, delta_exec); -cgroup_account_cputime (curtask, delta_exec); -account_group_exec_runtime (curtask, delta_exec); - } +if (entity_is_task (curr)) +update_curr_task (task_of (curr), delta_exec);account_cfs_rq_runtime (cfs_rq, delta_exec); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 329/356 sched/deadline: Collect sched_dl_entity initialization
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 9e07d45c5210f5dd6701c00d55791983db7320fa ]
Create a single function that initializes a sched_dl_entity.
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- kernel/sched/core.c | 5 +---- kernel/sched/deadline.c | 22 +++++++++++++++------- kernel/sched/sched.h | 5 +---- 3 files changed, 17 insertions(+), 15 deletions(-)
kernel/sched/core.c +1 -4
@@ -4513,10 +4513,7 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)memset (&p->stats,0 ,sizeof (p->stats));#endif -RB_CLEAR_NODE (&p->dl.rb_node); -init_dl_task_timer (&p->dl); -init_dl_inactive_task_timer (&p->dl); -__dl_clear_params (p); +init_dl_entity (&p->dl);INIT_LIST_HEAD (&p->rt.run_list); p->rt.timeout =0 ;
kernel/sched/deadline.c +15 -7
@@ -335,6 +335,8 @@ static void dl_change_utilization(struct task_struct *p, u64 new_bw)__add_rq_bw (new_bw, &rq->dl); } +static void __dl_clear_params (struct sched_dl_entity *dl_se); +/* * The utilization of a task cannot be immediately removed from * the rq active utilization (running_bw) when the task blocks.
@@ -434,7 +436,7 @@ static void task_non_contending(struct task_struct *p)raw_spin_lock (&dl_b->lock);__dl_sub (dl_b, p->dl.dl_bw,dl_bw_cpus (task_cpu (p)));raw_spin_unlock (&dl_b->lock); -__dl_clear_params (p); +__dl_clear_params (dl_se); }return ;
@@ -1207,7 +1209,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)return HRTIMER_NORESTART ; } -void init_dl_task_timer (struct sched_dl_entity *dl_se) +static void init_dl_task_timer (struct sched_dl_entity *dl_se) {struct hrtimer *timer = &dl_se->dl_timer;
@@ -1413,7 +1415,7 @@ static enum hrtimer_restart inactive_task_timer(struct hrtimer *timer)raw_spin_lock (&dl_b->lock);__dl_sub (dl_b, p->dl.dl_bw,dl_bw_cpus (task_cpu (p)));raw_spin_unlock (&dl_b->lock); -__dl_clear_params (p); +__dl_clear_params (dl_se); goto unlock; }
@@ -1429,7 +1431,7 @@ static enum hrtimer_restart inactive_task_timer(struct hrtimer *timer)return HRTIMER_NORESTART ; } -void init_dl_inactive_task_timer (struct sched_dl_entity *dl_se) +static void init_dl_inactive_task_timer (struct sched_dl_entity *dl_se) {struct hrtimer *timer = &dl_se->inactive_timer;
@@ -2986,10 +2988,8 @@ bool __checkparam_dl(const struct sched_attr *attr)/* * This function clears the sched_dl_entity static params. */ -void __dl_clear_params (struct task_struct *p) +static void __dl_clear_params (struct sched_dl_entity *dl_se) { -struct sched_dl_entity *dl_se = &p->dl; - dl_se->dl_runtime =0 ; dl_se->dl_deadline =0 ; dl_se->dl_period =0 ;
@@ -3007,6 +3007,14 @@ void __dl_clear_params(struct task_struct *p)#endif } +void init_dl_entity (struct sched_dl_entity *dl_se) +{ +RB_CLEAR_NODE (&dl_se->rb_node); +init_dl_task_timer (dl_se); +init_dl_inactive_task_timer (dl_se); +__dl_clear_params (dl_se); +} +bool dl_param_changed (struct task_struct *p,const struct sched_attr *attr) {struct sched_dl_entity *dl_se = &p->dl;
kernel/sched/sched.h +1 -4
@@ -286,8 +286,6 @@ struct rt_bandwidth {unsigned int rt_period_active; }; -void __dl_clear_params (struct task_struct *p); -static inline int dl_bandwidth_enabled (void ) {return sysctl_sched_rt_runtime >=0 ;
@@ -2446,8 +2444,7 @@ extern struct rt_bandwidth def_rt_bandwidth;extern void init_rt_bandwidth (struct rt_bandwidth *rt_b,u64 period,u64 runtime);extern bool sched_rt_bandwidth_account (struct rt_rq *rt_rq); -extern void init_dl_task_timer (struct sched_dl_entity *dl_se); -extern void init_dl_inactive_task_timer (struct sched_dl_entity *dl_se); +extern void init_dl_entity (struct sched_dl_entity *dl_se);#define BW_SHIFT 20#define BW_UNIT (1 << BW_SHIFT)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 330/356 sched/deadline: Move bandwidth accounting into {en,de}queue_dl_entity
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 2f7a0f58948d8231236e2facecc500f1930fb996 ]
In preparation of introducing !task sched_dl_entity; move the bandwidth accounting into {en.de}queue_dl_entity().
Stable-dep-of: 0664e2c311b9 ("sched/deadline: Fix warning in migrate_enable for boosted tasks")
--- kernel/sched/deadline.c | 130 ++++++++++++++++++++++------------------ kernel/sched/sched.h | 6 ++ 2 files changed, 78 insertions(+), 58 deletions(-)
kernel/sched/deadline.c +72 -58
@@ -391,12 +391,12 @@ static void __dl_clear_params(struct sched_dl_entity *dl_se);* up, and checks if the task is still in the "ACTIVE non contending" * state or not (in the second case, it updates running_bw). */ -static void task_non_contending (struct task_struct *p) +static void task_non_contending (struct sched_dl_entity *dl_se) { -struct sched_dl_entity *dl_se = &p->dl;struct hrtimer *timer = &dl_se->inactive_timer;struct dl_rq *dl_rq =dl_rq_of_se (dl_se);struct rq *rq =rq_of_dl_rq (dl_rq); +struct task_struct *p =dl_task_of (dl_se);s64 zerolag_time;/*
@@ -428,13 +428,14 @@ static void task_non_contending(struct task_struct *p)if ((zerolag_time <0 ) ||hrtimer_active (&dl_se->inactive_timer)) {if (dl_task (p))sub_running_bw (dl_se, dl_rq); +if (!dl_task (p) ||READ_ONCE (p->__state) ==TASK_DEAD ) {struct dl_bw *dl_b =dl_bw_of (task_cpu (p));if (READ_ONCE (p->__state) ==TASK_DEAD ) -sub_rq_bw (&p->dl, &rq->dl); +sub_rq_bw (dl_se, &rq->dl);raw_spin_lock (&dl_b->lock); -__dl_sub (dl_b, p->dl.dl_bw,dl_bw_cpus (task_cpu (p))); +__dl_sub (dl_b, dl_se->dl_bw,dl_bw_cpus (task_cpu (p)));raw_spin_unlock (&dl_b->lock);__dl_clear_params (dl_se); }
@@ -1627,6 +1628,41 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags)update_stats_enqueue_dl (dl_rq_of_se (dl_se), dl_se, flags); +/* +* Check if a constrained deadline task was activated +* after the deadline but before the next period. +* If that is the case, the task will be throttled and +* the replenishment timer will be set to the next period. +*/ +if (!dl_se->dl_throttled && !dl_is_implicit (dl_se)) +dl_check_constrained_dl (dl_se); + +if (flags & (ENQUEUE_RESTORE |ENQUEUE_MIGRATING )) { +struct dl_rq *dl_rq =dl_rq_of_se (dl_se); + +add_rq_bw (dl_se, dl_rq); +add_running_bw (dl_se, dl_rq); + } + +/* +* If p is throttled, we do not enqueue it. In fact, if it exhausted +* its budget it needs a replenishment and, since it now is on +* its rq, the bandwidth timer callback (which clearly has not +* run yet) will take care of this. +* However, the active utilization does not depend on the fact +* that the task is on the runqueue or not (but depends on the +* task's state - in GRUB parlance, "inactive" vs "active contending"). +* In other words, even if a task is throttled its utilization must +* be counted in the active utilization; hence, we need to call +* add_running_bw(). +*/ +if (dl_se->dl_throttled && !(flags &ENQUEUE_REPLENISH )) { +if (flags &ENQUEUE_WAKEUP ) +task_contending (dl_se, flags); + +return ; + } +/* * If this is a wakeup or a new instance, the scheduling * parameters of the task might need updating. Otherwise,
@@ -1646,9 +1682,28 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags)__enqueue_dl_entity (dl_se); } -static void dequeue_dl_entity (struct sched_dl_entity *dl_se) +static void dequeue_dl_entity (struct sched_dl_entity *dl_se,int flags) {__dequeue_dl_entity (dl_se); + +if (flags & (DEQUEUE_SAVE |DEQUEUE_MIGRATING )) { +struct dl_rq *dl_rq =dl_rq_of_se (dl_se); + +sub_running_bw (dl_se, dl_rq); +sub_rq_bw (dl_se, dl_rq); + } + +/* +* This check allows to start the inactive timer (or to immediately +* decrease the active utilization, if needed) in two cases: +* when the task blocks and when it is terminating +* (p->state == TASK_DEAD). We can handle the two cases in the same +* way, because from GRUB's point of view the same thing is happening +* (the task moves from "active contending" to "active non contending" +* or "inactive") +*/ +if (flags &DEQUEUE_SLEEP ) +task_non_contending (dl_se); }static void enqueue_task_dl (struct rq *rq,struct task_struct *p,int flags)
@@ -1693,76 +1748,35 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)return ; } -/* -* Check if a constrained deadline task was activated -* after the deadline but before the next period. -* If that is the case, the task will be throttled and -* the replenishment timer will be set to the next period. -*/ -if (!p->dl.dl_throttled && !dl_is_implicit (&p->dl)) -dl_check_constrained_dl (&p->dl); - -if (p->on_rq ==TASK_ON_RQ_MIGRATING || flags &ENQUEUE_RESTORE ) { -add_rq_bw (&p->dl, &rq->dl); -add_running_bw (&p->dl, &rq->dl); - } - -/* -* If p is throttled, we do not enqueue it. In fact, if it exhausted -* its budget it needs a replenishment and, since it now is on -* its rq, the bandwidth timer callback (which clearly has not -* run yet) will take care of this. -* However, the active utilization does not depend on the fact -* that the task is on the runqueue or not (but depends on the -* task's state - in GRUB parlance, "inactive" vs "active contending"). -* In other words, even if a task is throttled its utilization must -* be counted in the active utilization; hence, we need to call -* add_running_bw(). -*/ -if (p->dl.dl_throttled && !(flags &ENQUEUE_REPLENISH )) { -if (flags &ENQUEUE_WAKEUP ) -task_contending (&p->dl, flags); - -return ; - } -check_schedstat_required ();update_stats_wait_start_dl (dl_rq_of_se (&p->dl), &p->dl); +if (p->on_rq ==TASK_ON_RQ_MIGRATING ) + flags |=ENQUEUE_MIGRATING ; +enqueue_dl_entity (&p->dl, flags); -if (!task_current (rq, p) && p->nr_cpus_allowed >1 ) +if (!task_current (rq, p) && !p->dl.dl_throttled && p->nr_cpus_allowed >1 )enqueue_pushable_dl_task (rq, p); }static void __dequeue_task_dl (struct rq *rq,struct task_struct *p,int flags) {update_stats_dequeue_dl (&rq->dl, &p->dl, flags); -dequeue_dl_entity (&p->dl); -dequeue_pushable_dl_task (rq, p); +dequeue_dl_entity (&p->dl, flags); + +if (!p->dl.dl_throttled) +dequeue_pushable_dl_task (rq, p); }static void dequeue_task_dl (struct rq *rq,struct task_struct *p,int flags) {update_curr_dl (rq); -__dequeue_task_dl (rq, p, flags); -if (p->on_rq ==TASK_ON_RQ_MIGRATING || flags &DEQUEUE_SAVE ) { -sub_running_bw (&p->dl, &rq->dl); -sub_rq_bw (&p->dl, &rq->dl); - } +if (p->on_rq ==TASK_ON_RQ_MIGRATING ) + flags |=DEQUEUE_MIGRATING ; -/* -* This check allows to start the inactive timer (or to immediately -* decrease the active utilization, if needed) in two cases: -* when the task blocks and when it is terminating -* (p->state == TASK_DEAD). We can handle the two cases in the same -* way, because from GRUB's point of view the same thing is happening -* (the task moves from "active contending" to "active non contending" -* or "inactive") -*/ -if (flags &DEQUEUE_SLEEP ) -task_non_contending (p); +__dequeue_task_dl (rq, p, flags); }/*
@@ -2580,7 +2594,7 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p)* will reset the task parameters. */ if (task_on_rq_queued (p) && p->dl.dl_runtime) -task_non_contending (p); +task_non_contending (&p->dl);/* * In case a task is setscheduled out from SCHED_DEADLINE we need to
kernel/sched/sched.h +6 -0
@@ -2196,6 +2196,10 @@ extern const u32 sched_prio_to_wmult[40];* MOVE - paired with SAVE/RESTORE, explicitly does not preserve the location * in the runqueue. * +* NOCLOCK - skip the update_rq_clock() (avoids double updates) +* +* MIGRATION - p->on_rq == TASK_ON_RQ_MIGRATING (used for DEADLINE) +* * ENQUEUE_HEAD - place at front of runqueue (tail if not specified) * ENQUEUE_REPLENISH - CBS (replenish runtime and postpone deadline) * ENQUEUE_MIGRATED - the task was migrated during wakeup
@@ -2206,6 +2210,7 @@ extern const u32 sched_prio_to_wmult[40];#define DEQUEUE_SAVE 0x02/* Matches ENQUEUE_RESTORE */ #define DEQUEUE_MOVE 0x04/* Matches ENQUEUE_MOVE */ #define DEQUEUE_NOCLOCK 0x08/* Matches ENQUEUE_NOCLOCK */ +#define DEQUEUE_MIGRATING 0x100/* Matches ENQUEUE_MIGRATING */ #define ENQUEUE_WAKEUP 0x01#define ENQUEUE_RESTORE 0x02
@@ -2220,6 +2225,7 @@ extern const u32 sched_prio_to_wmult[40];#define ENQUEUE_MIGRATED 0x00#endif #define ENQUEUE_INITIAL 0x80 +#define ENQUEUE_MIGRATING 0x100#define RETRY_TASK ((void *)-1UL)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 331/356 sched/deadline: Fix warning in migrate_enable for boosted tasks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wander Lairson Costa <[email protected]>
[ Upstream commit 0664e2c311b9fa43b33e3e81429cd0c2d7f9c638 ]
When running the following command:
while true; do
stress-ng --cyclic 30 --timeout 30s --minimize --quiet
done
a warning is eventually triggered:
WARNING: CPU: 43 PID: 2848 at kernel/sched/deadline.c:794 setup_new_dl_entity+0x13e/0x180 ... Call Trace: <TASK> ? show_trace_log_lvl+0x1c4/0x2df ? enqueue_dl_entity+0x631/0x6e0 ? setup_new_dl_entity+0x13e/0x180 ? __warn+0x7e/0xd0 ? report_bug+0x11a/0x1a0 ? handle_bug+0x3c/0x70 ? exc_invalid_op+0x14/0x70 ? asm_exc_invalid_op+0x16/0x20 enqueue_dl_entity+0x631/0x6e0 enqueue_task_dl+0x7d/0x120 __do_set_cpus_allowed+0xe3/0x280 __set_cpus_allowed_ptr_locked+0x140/0x1d0 __set_cpus_allowed_ptr+0x54/0xa0 migrate_enable+0x7e/0x150 rt_spin_unlock+0x1c/0x90 group_send_sig_info+0xf7/0x1a0 ? kill_pid_info+0x1f/0x1d0 kill_pid_info+0x78/0x1d0 kill_proc_info+0x5b/0x110 __x64_sys_kill+0x93/0xc0 do_syscall_64+0x5c/0xf0 entry_SYSCALL_64_after_hwframe+0x6e/0x76 RIP: 0033:0x7f0dab31f92b
This warning occurs because set_cpus_allowed dequeues and enqueues tasks with the ENQUEUE_RESTORE flag set. If the task is boosted, the warning is triggered. A boosted task already had its parameters set by rt_mutex_setprio, and a new call to setup_new_dl_entity is unnecessary, hence the WARN_ON call.
Check if we are requeueing a boosted task and avoid calling setup_new_dl_entity if that's the case.
--- kernel/sched/deadline.c | 1 + 1 file changed, 1 insertion(+)
kernel/sched/deadline.c +1 -0
@@ -1674,6 +1674,7 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags) }else if (flags &ENQUEUE_REPLENISH ) {replenish_dl_entity (dl_se); }else if ((flags &ENQUEUE_RESTORE ) && + !is_dl_boosted (dl_se) &&dl_time_before (dl_se->deadline,rq_clock (rq_of_dl_rq (dl_rq_of_se (dl_se))))) {setup_new_dl_entity (dl_se);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 332/356 btrfs: fix missing snapshot drew unlock when root is dead during swap activation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 9c803c474c6c002d8ade68ebe99026cc39c37f85 ]
When activating a swap file we acquire the root's snapshot drew lock and then check if the root is dead, failing and returning with -EPERM if it's dead but without unlocking the root's snapshot lock. Fix this by adding the missing unlock.
--- fs/btrfs/inode.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/inode.c +1 -0
@@ -10693,6 +10693,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,if (btrfs_root_dead (root)) {spin_unlock (&root->root_item_lock); +btrfs_drew_write_unlock (&root->snapshot_lock);btrfs_exclop_finish (fs_info); btrfs_warn(fs_info, "cannot activate swapfile because subvolume %llu is being deleted",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 333/356 clk: en7523: Initialize num before accessing hws in en7523_register_clocks()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoyu Li <[email protected]>
[ Upstream commit 52fd1709e41d3a85b48bcfe2404a024ebaf30c3b ]
With the new __counted_by annotation in clk_hw_onecell_data, the "num" struct member must be set before accessing the "hws" array. Failing to do so will trigger a runtime warning when enabling CONFIG_UBSAN_BOUNDS and CONFIG_FORTIFY_SOURCE.
--- drivers/clk/clk-en7523.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/clk-en7523.c +2 -2
@@ -284,6 +284,8 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_datu32 rate;int i; + clk_data->num =EN7523_NUM_CLOCKS ; +for (i =0 ; i <ARRAY_SIZE (en7523_base_clks); i++) {const struct en_clk_desc *desc = &en7523_base_clks[i];
@@ -302,8 +304,6 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat hw =en7523_register_pcie_clk (dev, np_base); clk_data->hws[EN7523_CLK_PCIE ] = hw; - - clk_data->num =EN7523_NUM_CLOCKS ; }static int en7523_clk_probe (struct platform_device *pdev)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 334/356 tracing/eprobe: Fix to release eprobe when failed to add dyn_event
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
[ Upstream commit 494b332064c0ce2f7392fa92632bc50191c1b517 ]
Fix eprobe event to unregister event call and release eprobe when it fails to add dynamic event correctly.
--- kernel/trace/trace_eprobe.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/trace/trace_eprobe.c +5 -0
@@ -966,6 +966,11 @@ static int __trace_eprobe_create(int argc, const char *argv[]) goto error; } ret =dyn_event_add (&ep->devent, &ep->tp.event->call); +if (ret <0 ) { +trace_probe_unregister_event_call (&ep->tp); +mutex_unlock (&event_mutex); + goto error; + }mutex_unlock (&event_mutex);return ret; parse_error:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 335/356 x86: Fix build regression with CONFIG_KEXEC_JUMP enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit aeb68937614f4aeceaaa762bd7f0212ce842b797 ]
Build 6.13-rc12 for x86_64 with gcc 14.2.1 fails with the error:
ld: vmlinux.o: in function `virtual_mapped':
linux/arch/x86/kernel/relocate_kernel_64.S:249:(.text+0x5915b): undefined reference to `saved_context_gdt_desc'
when CONFIG_KEXEC_JUMP is enabled.
This was introduced by commit 07fa619f2a40 ("x86/kexec: Restore GDT on return from ::preserve_context kexec") which introduced a use of saved_context_gdt_desc without a declaration for it.
Fix that by including asm/asm-offsets.h where saved_context_gdt_desc is defined (indirectly in include/generated/asm-offsets.h which asm/asm-offsets.h includes).
--- arch/x86/kernel/relocate_kernel_64.S | 1 + 1 file changed, 1 insertion(+)
arch/x86/kernel/relocate_kernel_64.S +1 -0
@@ -11,6 +11,7 @@ #include <asm/pgtable_types.h> #include <asm/nospec-branch.h> #include <asm/unwind_hints.h> +#include <asm/asm-offsets.h> /* * Must be relocatable PIC code callable as a C function, in particular
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 336/356 Revert "unicode: Dont special case ignorable code points"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
[ Upstream commit 231825b2e1ff6ba799c5eaf396d3ab2354e37c6b ]
This reverts commit 5c26d2f1d3f5e4be3e196526bead29ecb139cf91.
It turns out that we can't do this, because while the old behavior of ignoring ignorable code points was most definitely wrong, we have case-folding filesystems with on-disk hash values with that wrong behavior.
So now you can't look up those names, because they hash to something different.
Of course, it's also entirely possible that in the meantime people have created *new* files with the new ("more correct") case folding logic, and reverting will just make other things break.
The correct solution is to not do case folding in filesystems, but sadly, people seem to never really understand that. People still see it as a feature, not a bug.
--- fs/unicode/mkutf8data.c | 70 + fs/unicode/utf8data.c_shipped | 6703 +++++++++++++++++---------------- 2 files changed, 3427 insertions(+), 3346 deletions(-)
fs/unicode/mkutf8data.c +70 -0
@@ -2230,6 +2230,75 @@ static void nfdicf_init(void)file_fail (fold_name); } +static void ignore_init (void ) +{ +FILE *file; +unsigned int unichar; +unsigned int first; +unsigned int last; +unsigned int *um; +int count; +int ret; + +if (verbose >0 ) +printf ("Parsing %s\n" , prop_name); + file =fopen (prop_name,"r" ); +if (!file) +open_fail (prop_name, errno); +assert (file); + count =0 ; +while (fgets (line,LINESIZE , file)) { + ret =sscanf (line,"%X..%X ; %s # " , &first, &last, buf0); +if (ret ==3 ) { +if (strcmp (buf0,"Default_Ignorable_Code_Point" )) +continue ; +if (!utf32valid (first) || !utf32valid (last)) +line_fail (prop_name, line); +for (unichar = first; unichar <= last; unichar++) { +free (unicode_data[unichar].utf32nfdi); + um =malloc (sizeof (unsigned int )); + *um =0 ; + unicode_data[unichar].utf32nfdi = um; +free (unicode_data[unichar].utf32nfdicf); + um =malloc (sizeof (unsigned int )); + *um =0 ; + unicode_data[unichar].utf32nfdicf = um; + count++; + } +if (verbose >1 ) +printf (" %X..%X Default_Ignorable_Code_Point\n" , + first, last); +continue ; + } + ret =sscanf (line,"%X ; %s # " , &unichar, buf0); +if (ret ==2 ) { +if (strcmp (buf0,"Default_Ignorable_Code_Point" )) +continue ; +if (!utf32valid (unichar)) +line_fail (prop_name, line); +free (unicode_data[unichar].utf32nfdi); + um =malloc (sizeof (unsigned int )); + *um =0 ; + unicode_data[unichar].utf32nfdi = um; +free (unicode_data[unichar].utf32nfdicf); + um =malloc (sizeof (unsigned int )); + *um =0 ; + unicode_data[unichar].utf32nfdicf = um; +if (verbose >1 ) +printf (" %X Default_Ignorable_Code_Point\n" , + unichar); + count++; +continue ; + } + } +fclose (file); + +if (verbose >0 ) +printf ("Found %d entries\n" , count); +if (count ==0 ) +file_fail (prop_name); +} +static void corrections_init (void ) {FILE *file;
@@ -3341,6 +3410,7 @@ int main(int argc, char *argv[])ccc_init ();nfdi_init ();nfdicf_init (); +ignore_init ();corrections_init ();hangul_decompose ();nfdi_decompose ();
fs/unicode/utf8data.c_shipped +3357 -3346
2,918 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.43.0
Part of the diff is not shown here. View the raw message.
Greg Kroah-Hartman
maintainerPATCH 337/356 vfio/mlx5: Align the page tracking max message size with the device capability
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <[email protected]>
[ Upstream commit 9c7c5430bca36e9636eabbba0b3b53251479c7ab ]
Align the page tracking maximum message size with the device's capability instead of relying on PAGE_SIZE.
This adjustment resolves a mismatch on systems where PAGE_SIZE is 64K, but the firmware only supports a maximum message size of 4K.
Now that we rely on the device's capability for max_message_size, we must account for potential future increases in its value.
Key considerations include:
- Supporting message sizes that exceed a single system page (e.g., an 8K message on a 4K system).
- Ensuring the RQ size is adjusted to accommodate at least 4 WQEs/messages, in line with the device specification.
The above has been addressed as part of the patch.
--- drivers/vfio/pci/mlx5/cmd.c | 47 +++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-)
drivers/vfio/pci/mlx5/cmd.c +35 -12
@@ -1368,7 +1368,8 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev,struct mlx5_vhca_qp *host_qp;struct mlx5_vhca_qp *fw_qp;struct mlx5_core_dev *mdev; -u32 max_msg_size =PAGE_SIZE ; +u32 log_max_msg_size; +u32 max_msg_size;u64 rq_size =SZ_2M ;u32 max_recv_wr;int err;
@@ -1385,6 +1386,12 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev, } mdev = mvdev->mdev; + log_max_msg_size =MLX5_CAP_ADV_VIRTUALIZATION (mdev, pg_track_log_max_msg_size); + max_msg_size = (1ULL << log_max_msg_size); +/* The RQ must hold at least 4 WQEs/messages for successful QP creation */ +if (rq_size <4 * max_msg_size) + rq_size =4 * max_msg_size; +memset (tracker,0 ,sizeof (*tracker)); tracker->uar =mlx5_get_uars_page (mdev);if (IS_ERR (tracker->uar)) {
@@ -1474,25 +1481,41 @@ set_report_output(u32 size, int index, struct mlx5_vhca_qp *qp, {u32 entry_size =MLX5_ST_SZ_BYTES (page_track_report_entry);u32 nent = size / entry_size; +u32 nent_in_page; +u32 nent_to_set;struct page *page; +u32 page_offset; +u32 page_index; +u32 buf_offset; +void *kaddr;u64 addr;u64 *buf;int i; -if (WARN_ON (index >= qp->recv_buf.npages || + buf_offset = index * qp->max_msg_size; +if (WARN_ON (buf_offset + size >= qp->recv_buf.npages *PAGE_SIZE || (nent > qp->max_msg_size / entry_size)))return ; - page = qp->recv_buf.page_list[index]; - buf =kmap_local_page (page); -for (i =0 ; i < nent; i++) { - addr =MLX5_GET (page_track_report_entry, buf + i, - dirty_address_low); - addr |= (u64 )MLX5_GET (page_track_report_entry, buf + i, - dirty_address_high) <<32 ; -iova_bitmap_set (dirty, addr, qp->tracked_page_size); - } -kunmap_local (buf); +do { + page_index = buf_offset /PAGE_SIZE ; + page_offset = buf_offset %PAGE_SIZE ; + nent_in_page = (PAGE_SIZE - page_offset) / entry_size; + page = qp->recv_buf.page_list[page_index]; + kaddr =kmap_local_page (page); + buf = kaddr + page_offset; + nent_to_set =min (nent, nent_in_page); +for (i =0 ; i < nent_to_set; i++) { + addr =MLX5_GET (page_track_report_entry, buf + i, + dirty_address_low); + addr |= (u64 )MLX5_GET (page_track_report_entry, buf + i, + dirty_address_high) <<32 ; +iova_bitmap_set (dirty, addr, qp->tracked_page_size); + } +kunmap_local (kaddr); + buf_offset += (nent_to_set * entry_size); + nent -= nent_to_set; + }while (nent); } static void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 338/356 selftests/ftrace: adjust offset for kprobe syntax error test
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hari Bathini <[email protected]>
[ Upstream commit 777f290ab328de333b85558bb6807a69a59b36ba ]
In 'NOFENTRY_ARGS' test case for syntax check, any offset X of vfs_read+X except function entry offset (0) fits the criterion, even if that offset is not at instruction boundary, as the parser comes before probing. But with "ENDBR64" instruction on x86, offset 4 is treated as function entry. So, X can't be 4 as well. Thus, 8 was used as offset for the test case. On 64-bit powerpc though, any offset <= 16 can be considered function entry depending on build configuration (see arch_kprobe_on_func_entry() for implementation details). So, use vfs_read+20 to accommodate that scenario too.
--- tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc +1 -1
@@ -111,7 +111,7 @@ check_error 'p vfs_read $arg* ^$arg*' # if !grep -q 'kernel return probes support:' README; then check_error 'r vfs_read ^$arg*' # NOFENTRY_ARGS fi -check_error 'p vfs_read+8 ^$arg*' # NOFENTRY_ARGS +check_error 'p vfs_read+20 ^$arg*' # NOFENTRY_ARGS check_error 'p vfs_read ^hoge' # NO_BTFARG check_error 'p kfree ^$arg10' # NO_BTFARG (exceed the number of parameters) check_error 'r kfree ^$retval' # NO_RETVAL
Greg Kroah-Hartman
maintainerPATCH 339/356 KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from kvm_faultin_pfn()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Kuratov <[email protected]>
Since 5.16 and prior to 6.13 KVM can't be used with FSDAX guest memory (PMD pages). To reproduce the issue you need to reserve guest memory with memmap= cmdline, create and mount FS in DAX mode (tested both XFS and ext4), see doc link below. ndctl command for test:
ndctl create-namespace -v -e namespace1.0 --map=dev --mode=fsdax -a 2M Then pass memory object to qemu like:
-m 8G -object memory-backend-file,id=ram0,size=8G,\
mem-path=/mnt/pmem/guestmem,share=on,prealloc=on,dump=off,align=2097152 \
-numa node,memdev=ram0,cpus=0-1
QEMU fails to run guest with error: kvm run failed Bad address and there are two warnings in dmesg:
WARN_ON_ONCE(!page_count(page)) in kvm_is_zone_device_page() and WARN_ON_ONCE(folio_ref_count(folio) <= 0) in try_grab_folio() (v6.6.63)
It looks like in the past assumption was made that pfn won't change from faultin_pfn() to release_pfn_clean(), e.g. see
commit 4cd071d13c5c ("KVM: x86/mmu: Move calls to thp_adjust() down a level") But kvm_page_fault structure made pfn part of mutable state, so now release_pfn_clean() can take hugepage-adjusted pfn.
And it works for all cases (/dev/shm, hugetlb, devdax) except fsdax. Apparently in fsdax mode faultin-pfn and adjusted-pfn may refer to different folios, so we're getting get_page/put_page imbalance.
To solve this preserve faultin pfn in separate local variable and pass it in kvm_release_pfn_clean().
Patch tested for all mentioned guest memory backends with tdp_mmu={0,1}.
No bug in upstream as it was solved fundamentally by
commit 8dd861cc07e2 ("KVM: x86/mmu: Put refcounted pages instead of blindly releasing pfns") and related patch series.
--- arch/x86/kvm/mmu/mmu.c | 10 ++++++++-- arch/x86/kvm/mmu/paging_tmpl.h | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-)
arch/x86/kvm/mmu/mmu.c +8 -2
@@ -4363,6 +4363,7 @@ static bool is_page_fault_stale(struct kstatic int direct_page_fault (struct kvm_vcpu *vcpu,struct kvm_page_fault *fault) { +kvm_pfn_t orig_pfn;int r;/* Dummy roots are used only for shadowing bad guest roots. */
@@ -4384,6 +4385,8 @@ static int direct_page_fault(struct kvm_if (r !=RET_PF_CONTINUE )return r; + orig_pfn = fault->pfn; + r =RET_PF_RETRY ;write_lock (&vcpu->kvm->mmu_lock);
@@ -4398,7 +4401,7 @@ static int direct_page_fault(struct kvm_ out_unlock:write_unlock (&vcpu->kvm->mmu_lock); -kvm_release_pfn_clean (fault->pfn); +kvm_release_pfn_clean (orig_pfn);return r; }
@@ -4447,6 +4450,7 @@ EXPORT_SYMBOL_GPL(kvm_handle_page_fault)static int kvm_tdp_mmu_page_fault (struct kvm_vcpu *vcpu,struct kvm_page_fault *fault) { +kvm_pfn_t orig_pfn;int r;if (page_fault_handle_page_track (vcpu, fault))
@@ -4464,6 +4468,8 @@ static int kvm_tdp_mmu_page_fault(structif (r !=RET_PF_CONTINUE )return r; + orig_pfn = fault->pfn; + r =RET_PF_RETRY ;read_lock (&vcpu->kvm->mmu_lock);
@@ -4474,7 +4480,7 @@ static int kvm_tdp_mmu_page_fault(struct out_unlock:read_unlock (&vcpu->kvm->mmu_lock); -kvm_release_pfn_clean (fault->pfn); +kvm_release_pfn_clean (orig_pfn); return r; }#endif
arch/x86/kvm/mmu/paging_tmpl.h +4 -1
@@ -777,6 +777,7 @@ out_gpte_changed:static int FNAME (page_fault )(struct kvm_vcpu *vcpu,struct kvm_page_fault *fault) {struct guest_walker walker; +kvm_pfn_t orig_pfn;int r;WARN_ON_ONCE (fault->is_tdp);
@@ -835,6 +836,8 @@ static int FNAME(page_fault)(struct kvm_ walker.pte_access &= ~ACC_EXEC_MASK ; } + orig_pfn = fault->pfn; + r =RET_PF_RETRY ;write_lock (&vcpu->kvm->mmu_lock);
@@ -848,7 +851,7 @@ static int FNAME(page_fault)(struct kvm_ out_unlock:write_unlock (&vcpu->kvm->mmu_lock); -kvm_release_pfn_clean (fault->pfn); +kvm_release_pfn_clean (orig_pfn);return r; }
Greg Kroah-Hartman
maintainerPATCH 340/356 jffs2: Prevent rtime decompress memory corruption
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kinsey Moore <[email protected]>
commit fe051552f5078fa02d593847529a3884305a6ffe upstream.
The rtime decompression routine does not fully check bounds during the entirety of the decompression pass and can corrupt memory outside the decompression buffer if the compressed data is corrupted. This adds the required check to prevent this failure mode.
--- fs/jffs2/compr_rtime.c | 3 +++ 1 file changed, 3 insertions(+)
fs/jffs2/compr_rtime.c +3 -0
@@ -95,6 +95,9 @@ static int jffs2_rtime_decompress(unsign positions[value]=outpos;if (repeat) { +if ((outpos + repeat) >= destlen) { +return 1 ; + }if (backoffs + repeat >= outpos) {while (repeat) { cpage_out[outpos++] = cpage_out[backoffs++];
Greg Kroah-Hartman
maintainerPATCH 341/356 jffs2: Fix rtime decompressor
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <[email protected]>
commit b29bf7119d6bbfd04aabb8d82b060fe2a33ef890 upstream.
The fix for a memory corruption contained a off-by-one error and caused the compressor to fail in legit cases.
--- fs/jffs2/compr_rtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jffs2/compr_rtime.c +1 -1
@@ -95,7 +95,7 @@ static int jffs2_rtime_decompress(unsign positions[value]=outpos;if (repeat) { -if ((outpos + repeat) >= destlen) { +if ((outpos + repeat) > destlen) {return 1 ; }if (backoffs + repeat >= outpos) {
Greg Kroah-Hartman
maintainerPATCH 342/356 mm/damon/vaddr: fix issue in damon_va_evenly_split_region()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Yejian <[email protected]>
commit f3c7a1ede435e2e45177d7a490a85fb0a0ec96d1 upstream.
Patch series "mm/damon/vaddr: Fix issue indamon_va_evenly_split_region()". v2.
According to the logic of damon_va_evenly_split_region(), currently following split case would not meet the expectation:
Suppose DAMON_MIN_REGION=0x1000,
Case: Split [0x0, 0x3000) into 2 pieces, then the result would be
acutually 3 regions:
[0x0, 0x1000), [0x1000, 0x2000), [0x2000, 0x3000)
but NOT the expected 2 regions:
[0x0, 0x1000), [0x1000, 0x3000) !!!
The root cause is that when calculating size of each split piece in damon_va_evenly_split_region():
sz_piece = ALIGN_DOWN(sz_orig / nr_pieces, DAMON_MIN_REGION);
both the dividing and the ALIGN_DOWN may cause loss of precision, then each time split one piece of size 'sz_piece' from origin 'start' to 'end' would cause more pieces are split out than expected!!!
To fix it, count for each piece split and make sure no more than 'nr_pieces'. In addition, add above case into damon_test_split_evenly().
And add 'nr_piece == 1' check in damon_va_evenly_split_region() for better code readability and add a corresponding kunit testcase.
This patch (of 2):
According to the logic of damon_va_evenly_split_region(), currently following split case would not meet the expectation:
Suppose DAMON_MIN_REGION=0x1000,
Case: Split [0x0, 0x3000) into 2 pieces, then the result would be
acutually 3 regions:
[0x0, 0x1000), [0x1000, 0x2000), [0x2000, 0x3000)
but NOT the expected 2 regions:
[0x0, 0x1000), [0x1000, 0x3000) !!!
The root cause is that when calculating size of each split piece in damon_va_evenly_split_region():
sz_piece = ALIGN_DOWN(sz_orig / nr_pieces, DAMON_MIN_REGION);
both the dividing and the ALIGN_DOWN may cause loss of precision, then each time split one piece of size 'sz_piece' from origin 'start' to 'end' would cause more pieces are split out than expected!!!
To fix it, count for each piece split and make sure no more than 'nr_pieces'. In addition, add above case into damon_test_split_evenly().
After this patch, damon-operations test passed:
# ./tools/testing/kunit/kunit.py run damon-operations [...] ============== damon-operations (6 subtests) =============== [PASSED] damon_test_three_regions_in_vmas [PASSED] damon_test_apply_three_regions1 [PASSED] damon_test_apply_three_regions2 [PASSED] damon_test_apply_three_regions3 [PASSED] damon_test_apply_three_regions4 [PASSED] damon_test_split_evenly ================ [PASSED] damon-operations =================
--- mm/damon/vaddr-test.h | 1 + mm/damon/vaddr.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-)
mm/damon/vaddr-test.h +1 -0
@@ -300,6 +300,7 @@ static void damon_test_split_evenly(strudamon_test_split_evenly_fail (test,0 ,100 ,0 );damon_test_split_evenly_succ (test,0 ,100 ,10 );damon_test_split_evenly_succ (test,5 ,59 ,5 ); +damon_test_split_evenly_succ (test,0 ,3 ,2 );damon_test_split_evenly_fail (test,5 ,6 ,2 ); }
mm/damon/vaddr.c +2 -2
@@ -67,6 +67,7 @@ static int damon_va_evenly_split_region(unsigned long sz_orig, sz_piece, orig_end;struct damon_region *n =NULL , *next;unsigned long start; +unsigned int i;if (!r || !nr_pieces)return -EINVAL ;
@@ -80,8 +81,7 @@ static int damon_va_evenly_split_region( r->ar.end = r->ar.start + sz_piece; next =damon_next_region (r); -for (start = r->ar.end; start + sz_piece <= orig_end; - start += sz_piece) { +for (start = r->ar.end, i =1 ; i < nr_pieces; start += sz_piece, i++) { n =damon_new_region (start, start + sz_piece);if (!n)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 343/356 xhci: dbc: Fix STALL transfer event handling
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit 9044ad57b60b0556d42b6f8aa218a68865e810a4 upstream.
Don't flush all pending DbC data requests when an endpoint halts.
An endpoint may halt and xHC DbC triggers a STALL error event if there's an issue with a bulk data transfer. The transfer should restart once xHC DbC receives a ClearFeature(ENDPOINT_HALT) request from the host.
Once xHC DbC restarts it will start from the TRB pointed to by dequeue field in the endpoint context, which might be the same TRB we got the STALL event for. Turn the TRB to a no-op in this case to make sure xHC DbC doesn't reuse and tries to retransmit this same TRB after we already handled it, and gave its corresponding data request back.
Other STALL events might be completely bogus.
Lukasz Bartosik discovered that xHC DbC might issue spurious STALL events if hosts sends a ClearFeature(ENDPOINT_HALT) request to non-halted endpoints even without any active bulk transfers.
Assume STALL event is spurious if it reports 0 bytes transferred, and the endpoint stopped on the STALLED TRB.
Don't give back the data request corresponding to the TRB in this case.
The halted status is per endpoint. Track it with a per endpoint flag instead of the driver invented DbC wide DS_STALLED state. DbC remains in DbC-Configured state even if endpoints halt. There is no Stalled state in the DbC Port state Machine (xhci section 7.6.6)
--- drivers/usb/host/xhci-dbgcap.c | 135 ++++++++++++++++++++++++----------------- drivers/usb/host/xhci-dbgcap.h | 2 2 files changed, 83 insertions(+), 54 deletions(-)
drivers/usb/host/xhci-dbgcap.c +82 -53
@@ -158,16 +158,18 @@ static void xhci_dbc_giveback(struct dbcspin_lock (&dbc->lock); } -static void xhci_dbc_flush_single_request (struct dbc_request *req) +static void trb_to_noop (union xhci_trb *trb) { -union xhci_trb *trb = req->trb; - trb->generic.field[0 ] =0 ; trb->generic.field[1 ] =0 ; trb->generic.field[2 ] =0 ; trb->generic.field[3 ] &=cpu_to_le32 (TRB_CYCLE ); trb->generic.field[3 ] |=cpu_to_le32 (TRB_TYPE (TRB_TR_NOOP )); +} +static void xhci_dbc_flush_single_request (struct dbc_request *req) +{ +trb_to_noop (req->trb);xhci_dbc_giveback (req, -ESHUTDOWN ); }
@@ -637,7 +639,6 @@ static void xhci_dbc_stop(struct xhci_dbcase DS_DISABLED :return ;case DS_CONFIGURED : -case DS_STALLED :if (dbc->driver->disconnect) dbc->driver->disconnect (dbc);break ;
@@ -658,6 +659,23 @@ static void xhci_dbc_stop(struct xhci_db }static void +handle_ep_halt_changes (struct xhci_dbc *dbc,struct dbc_ep *dep,bool halted) +{ +if (halted) { +dev_info (dbc->dev,"DbC Endpoint halted\n" ); + dep->halted =1 ; + + }else if (dep->halted) { +dev_info (dbc->dev,"DbC Endpoint halt cleared\n" ); + dep->halted =0 ; + +if (!list_empty (&dep->list_pending)) +writel (DBC_DOOR_BELL_TARGET (dep->direction), + &dbc->regs->doorbell); + } +} + +static void dbc_handle_port_status (struct xhci_dbc *dbc,union xhci_trb *event) {u32 portsc;
@@ -685,6 +703,7 @@ static void dbc_handle_xfer_event(structstruct xhci_ring *ring;int ep_id;int status; +struct xhci_ep_ctx *ep_ctx;u32 comp_code;size_t remain_length;struct dbc_request *req =NULL , *r;
@@ -694,8 +713,30 @@ static void dbc_handle_xfer_event(struct ep_id =TRB_TO_EP_ID (le32_to_cpu (event->generic.field[3 ])); dep = (ep_id ==EPID_OUT ) ?get_out_ep (dbc) :get_in_ep (dbc); + ep_ctx = (ep_id ==EPID_OUT ) ? +dbc_bulkout_ctx (dbc) :dbc_bulkin_ctx (dbc); ring = dep->ring; +/* Match the pending request: */ +list_for_each_entry (r, &dep->list_pending, list_pending) { +if (r->trb_dma == event->trans_event.buffer) { + req = r; +break ; + } +if (r->status == -COMP_STALL_ERROR ) { +dev_warn (dbc->dev,"Give back stale stalled req\n" ); + ring->num_trbs_free++; +xhci_dbc_giveback (r,0 ); + } + } + +if (!req) { +dev_warn (dbc->dev,"no matched request\n" ); +return ; + } + +trace_xhci_dbc_handle_transfer (ring, &req->trb->generic); +switch (comp_code) {case COMP_SUCCESS : remain_length =0 ;
@@ -706,31 +747,49 @@ static void dbc_handle_xfer_event(structcase COMP_TRB_ERROR :case COMP_BABBLE_DETECTED_ERROR :case COMP_USB_TRANSACTION_ERROR : -case COMP_STALL_ERROR :dev_warn (dbc->dev,"tx error %d detected\n" , comp_code); status = -comp_code;break ; +case COMP_STALL_ERROR : +dev_warn (dbc->dev,"Stall error at bulk TRB %llx, remaining %zu, ep deq %llx\n" , + event->trans_event.buffer, remain_length, ep_ctx->deq); + status =0 ; + dep->halted =1 ; + +/* +* xHC DbC may trigger a STALL bulk xfer event when host sends a +* ClearFeature(ENDPOINT_HALT) request even if there wasn't an +* active bulk transfer. +* +* Don't give back this transfer request as hardware will later +* start processing TRBs starting from this 'STALLED' TRB, +* causing TRBs and requests to be out of sync. +* +* If STALL event shows some bytes were transferred then assume +* it's an actual transfer issue and give back the request. +* In this case mark the TRB as No-Op to avoid hw from using the +* TRB again. +*/ + +if ((ep_ctx->deq & ~TRB_CYCLE ) == event->trans_event.buffer) { +dev_dbg (dbc->dev,"Ep stopped on Stalled TRB\n" ); +if (remain_length == req->length) { +dev_dbg (dbc->dev,"Spurious stall event, keep req\n" ); + req->status = -COMP_STALL_ERROR ; + req->actual =0 ; +return ; + } +dev_dbg (dbc->dev,"Give back stalled req, but turn TRB to No-op\n" ); +trb_to_noop (req->trb); + } +break ; +default :dev_err (dbc->dev,"unknown tx error %d\n" , comp_code); status = -comp_code;break ; } -/* Match the pending request: */ -list_for_each_entry (r, &dep->list_pending, list_pending) { -if (r->trb_dma == event->trans_event.buffer) { - req = r; -break ; - } - } - -if (!req) { -dev_warn (dbc->dev,"no matched request\n" ); -return ; - } - -trace_xhci_dbc_handle_transfer (ring, &req->trb->generic); - ring->num_trbs_free++; req->actual = req->length - remain_length;xhci_dbc_giveback (req, status);
@@ -750,7 +809,6 @@ static void inc_evt_deq(struct xhci_ringstatic enum evtreturn xhci_dbc_do_handle_events (struct xhci_dbc *dbc) {dma_addr_t deq; -struct dbc_ep *dep;union xhci_trb *evt;u32 ctrl, portsc;bool update_erdp = false;
@@ -802,43 +860,17 @@ static enum evtreturn xhci_dbc_do_handlereturn EVT_DISC ; } -/* Handle endpoint stall event: */ +/* Check and handle changes in endpoint halt status */ ctrl =readl (&dbc->regs->control); -if ((ctrl &DBC_CTRL_HALT_IN_TR ) || - (ctrl &DBC_CTRL_HALT_OUT_TR )) { -dev_info (dbc->dev,"DbC Endpoint stall\n" ); - dbc->state =DS_STALLED ; - -if (ctrl &DBC_CTRL_HALT_IN_TR ) { - dep =get_in_ep (dbc); -xhci_dbc_flush_endpoint_requests (dep); - } - -if (ctrl &DBC_CTRL_HALT_OUT_TR ) { - dep =get_out_ep (dbc); -xhci_dbc_flush_endpoint_requests (dep); - } - -return EVT_DONE ; - } +handle_ep_halt_changes (dbc,get_in_ep (dbc), ctrl &DBC_CTRL_HALT_IN_TR ); +handle_ep_halt_changes (dbc,get_out_ep (dbc), ctrl &DBC_CTRL_HALT_OUT_TR );/* Clear DbC run change bit: */ if (ctrl &DBC_CTRL_DBC_RUN_CHANGE ) {writel (ctrl, &dbc->regs->control); ctrl =readl (&dbc->regs->control); } -break ; -case DS_STALLED : - ctrl =readl (&dbc->regs->control); -if (!(ctrl &DBC_CTRL_HALT_IN_TR ) && - !(ctrl &DBC_CTRL_HALT_OUT_TR ) && - (ctrl &DBC_CTRL_DBC_RUN )) { - dbc->state =DS_CONFIGURED ; -break ; - } - -return EVT_DONE ;default :dev_err (dbc->dev,"Unknown DbC state %d\n" , dbc->state);break ;
@@ -941,9 +973,6 @@ static ssize_t dbc_show(struct device *dcase DS_CONFIGURED : p ="configured" ;break ; -case DS_STALLED : - p ="stalled" ; -break ;default : p ="unknown" ; }
drivers/usb/host/xhci-dbgcap.h +1 -1
@@ -81,7 +81,6 @@ enum dbc_state {DS_ENABLED ,DS_CONNECTED , DS_CONFIGURED, - DS_STALLED, }; struct dbc_ep {
@@ -89,6 +88,7 @@ struct dbc_ep {struct list_head list_pending;struct xhci_ring *ring; unsigned int direction:1; + unsigned int halted:1; };#define DBC_QUEUE_SIZE 16
Greg Kroah-Hartman
maintainerPATCH 344/356 iio: invensense: fix multiple odr switch when FIFO is off
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Baptiste Maneyrol <[email protected]>
commit ef5f5e7b6f73f79538892a8be3a3bee2342acc9f upstream.
When multiple ODR switch happens during FIFO off, the change could not be taken into account if you get back to previous FIFO on value. For example, if you run sensor buffer at 50Hz, stop, change to 200Hz, then back to 50Hz and restart buffer, data will be timestamped at 200Hz. This due to testing against mult and not new_mult.
To prevent this, let's just run apply_odr automatically when FIFO is off. It will also simplify driver code.
Update inv_mpu6050 and inv_icm42600 to delete now useless apply_odr.
--- drivers/iio/common/inv_sensors/inv_sensors_timestamp.c | 4 ++++ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 2 -- drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 2 -- drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 1 - 4 files changed, 4 insertions(+), 5 deletions(-)
drivers/iio/common/inv_sensors/inv_sensors_timestamp.c +4 -0
@@ -70,6 +70,10 @@ int inv_sensors_timestamp_update_odr(strif (mult != ts->mult) ts->new_mult = mult; +/* When FIFO is off, directly apply the new ODR */ +if (!fifo) +inv_sensors_timestamp_apply_odr (ts,0 ,0 ,0 ); +return 0 ; }EXPORT_SYMBOL_NS_GPL (inv_sensors_timestamp_update_odr,IIO_INV_SENSORS_TIMESTAMP );
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +0 -2
@@ -99,7 +99,6 @@ static int inv_icm42600_accel_update_sca const unsigned long *scan_mask) {struct inv_icm42600_state *st =iio_device_get_drvdata (indio_dev); -struct inv_sensors_timestamp *ts =iio_priv (indio_dev);struct inv_icm42600_sensor_conf conf =INV_ICM42600_SENSOR_CONF_INIT ;unsigned int fifo_en =0 ;unsigned int sleep_temp =0 ;
@@ -127,7 +126,6 @@ static int inv_icm42600_accel_update_sca }/* update data FIFO write */ -inv_sensors_timestamp_apply_odr (ts,0 ,0 ,0 ); ret =inv_icm42600_buffer_set_fifo_en (st, fifo_en | st->fifo.en); out_unlock:
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +0 -2
@@ -99,7 +99,6 @@ static int inv_icm42600_gyro_update_scan const unsigned long *scan_mask) {struct inv_icm42600_state *st =iio_device_get_drvdata (indio_dev); -struct inv_sensors_timestamp *ts =iio_priv (indio_dev);struct inv_icm42600_sensor_conf conf =INV_ICM42600_SENSOR_CONF_INIT ;unsigned int fifo_en =0 ;unsigned int sleep_gyro =0 ;
@@ -127,7 +126,6 @@ static int inv_icm42600_gyro_update_scan }/* update data FIFO write */ -inv_sensors_timestamp_apply_odr (ts,0 ,0 ,0 ); ret =inv_icm42600_buffer_set_fifo_en (st, fifo_en | st->fifo.en); out_unlock:
drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +0 -1
@@ -111,7 +111,6 @@ int inv_mpu6050_prepare_fifo(struct inv_if (enable) {/* reset timestamping */ inv_sensors_timestamp_reset (&st->timestamp); -inv_sensors_timestamp_apply_odr (&st->timestamp,0 ,0 ,0 );/* reset FIFO */ d = st->chip_config.user_ctrl |INV_MPU6050_BIT_FIFO_RST ; ret =regmap_write (st->map, st->reg->user_ctrl, d);
Greg Kroah-Hartman
maintainerPATCH 345/356 btrfs: add cancellation points to trim loops
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Stefani <[email protected]>
commit 69313850dce33ce8c24b38576a279421f4c60996 upstream.
There are reports that system cannot suspend due to running trim because the task responsible for trimming the device isn't able to finish in time, especially since we have a free extent discarding phase, which can trim a lot of unallocated space. There are no limits on the trim size (unlike the block group part).
Since trime isn't a critical call it can be interrupted at any time, in such cases we stop the trim, report the amount of discarded bytes and return an error.
--- fs/btrfs/extent-tree.c | 7 ++++++- fs/btrfs/free-space-cache.c | 4 ++-- fs/btrfs/free-space-cache.h | 7 +++++++ 3 files changed, 15 insertions(+), 3 deletions(-)
fs/btrfs/extent-tree.c +6 -1
@@ -1319,6 +1319,11 @@ static int btrfs_issue_discard(struct bl start += bytes_to_discard; bytes_left -= bytes_to_discard; *discarded_bytes += bytes_to_discard; + +if (btrfs_trim_interrupted ()) { + ret = -ERESTARTSYS ; +break ; + } }return ret;
@@ -6097,7 +6102,7 @@ static int btrfs_trim_free_extents(struc start += len; *trimmed += bytes; -if (fatal_signal_pending (current)) { +if (btrfs_trim_interrupted ()) { ret = -ERESTARTSYS ;break ; }
fs/btrfs/free-space-cache.c +2 -2
@@ -3808,7 +3808,7 @@ next:if (async && *total_trimmed)break ; -if (fatal_signal_pending (current)) { +if (btrfs_trim_interrupted ()) { ret = -ERESTARTSYS ;break ; }
@@ -3999,7 +3999,7 @@ next: } block_group->discard_cursor = start; -if (fatal_signal_pending (current)) { +if (btrfs_trim_interrupted ()) {if (start != offset)reset_trimming_bitmap (ctl, offset); ret = -ERESTARTSYS ;
fs/btrfs/free-space-cache.h +7 -0
@@ -6,6 +6,8 @@#ifndef BTRFS_FREE_SPACE_CACHE_H #define BTRFS_FREE_SPACE_CACHE_H +#include <linux/freezer.h> +/* * This is the trim state of an extent or bitmap. *
@@ -43,6 +45,11 @@ static inline bool btrfs_free_space_trimreturn (info->trim_state ==BTRFS_TRIM_STATE_TRIMMING ); } +static inline bool btrfs_trim_interrupted (void ) +{ +return fatal_signal_pending (current) ||freezing (current); +} +/* * Deltas are an effective way to populate global statistics. Give macro names * to make it clear what we're doing. An example is discard_extents in
Greg Kroah-Hartman
maintainerPATCH 346/356 ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heming Zhao <[email protected]>
This reverts commit dfe6c5692fb5 ("ocfs2: fix the la space leak when unmounting an ocfs2 volume").
In commit dfe6c5692fb5, the commit log "This bug has existed since the initial OCFS2 code." is wrong. The correct introduction commit is 30dd3478c3cd ("ocfs2: correctly use ocfs2_find_next_zero_bit()").
The influence of commit dfe6c5692fb5 is that it provides a correct fix for the latest kernel. however, it shouldn't be pushed to stable branches. Let's use this commit to revert all branches that include dfe6c5692fb5 and use a new fix method to fix commit 30dd3478c3cd.
--- fs/ocfs2/localalloc.c | 19 ------------------- 1 file changed, 19 deletions(-)
fs/ocfs2/localalloc.c +0 -19
@@ -1008,25 +1008,6 @@ static int ocfs2_sync_local_to_main(stru start = bit_off +1 ; } -/* clear the contiguous bits until the end boundary */ -if (count) { - blkno = la_start_blk + -ocfs2_clusters_to_blocks (osb->sb, - start - count); - -trace_ocfs2_sync_local_to_main_free ( - count, start - count, - (unsigned long long )la_start_blk, - (unsigned long long )blkno); - - status =ocfs2_release_clusters (handle, - main_bm_inode, - main_bm_bh, blkno, - count); -if (status <0 ) -mlog_errno (status); - } - bail:if (status)mlog_errno (status);
Greg Kroah-Hartman
maintainerPATCH 347/356 ASoC: Intel: avs: Fix return status of avs_pcm_hw_constraints_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amadeusz Sławiński <[email protected]>
commit a0aae96be5ffc5b456ca07bfe1385b721c20e184 upstream.
Check for return code from avs_pcm_hw_constraints_init() in avs_dai_fe_startup() only checks if value is different from 0. Currently function can return positive value, change it to return 0 on success.
I've observed KASAN on our setups and while patch itself is correct regardless. Problem seems to be caused by recent changes to rates, as this started happening after recent patchsets and doesn't reproduce with those reverted
https://lore.kernel.org/linux-sound/[email protected]/
https://lore.kernel.org/linux-sound/[email protected]/
I've tested using Mark tree, where they are both applied and for some reason snd_pcm_hw_constraint_minmax() started returning positive value, while previously it returned 0. I'm bit worried if it signals some potential deeper problem regarding constraints with above changes.
--- sound/soc/intel/avs/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/intel/avs/pcm.c +1 -1
@@ -424,7 +424,7 @@ static int avs_dai_hda_be_trigger(structbreak ; } -return ret; +return 0 ; }static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
Greg Kroah-Hartman
maintainerPATCH 348/356 drm/amdgpu: rework resume handling for display (v2)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 73dae652dcac776296890da215ee7dec357a1032 upstream.
Split resume into a 3rd step to handle displays when DCC is enabled on DCN 4.0.1. Move display after the buffer funcs have been re-enabled so that the GPU will do the move and properly set the DCC metadata for DCN.
v2: fix fence irq resume ordering
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 45 +++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +43 -2
@@ -3172,7 +3172,7 @@ static int amdgpu_device_ip_resume_phase* * @adev: amdgpu_device pointer * -* First resume function for hardware IPs. The list of all the hardware +* Second resume function for hardware IPs. The list of all the hardware * IPs that make up the asic is walked and the resume callbacks are run for * all blocks except COMMON, GMC, and IH. resume puts the hardware into a * functional state after a suspend and updates the software state as
@@ -3190,6 +3190,7 @@ static int amdgpu_device_ip_resume_phaseif (adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_COMMON || adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_GMC || adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_IH || + adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_DCE || adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_PSP )continue ; r = adev->ip_blocks[i].version->funcs->resume (adev);
@@ -3205,6 +3206,36 @@ static int amdgpu_device_ip_resume_phase }/** +* amdgpu_device_ip_resume_phase3 - run resume for hardware IPs +* +* @adev: amdgpu_device pointer +* +* Third resume function for hardware IPs. The list of all the hardware +* IPs that make up the asic is walked and the resume callbacks are run for +* all DCE. resume puts the hardware into a functional state after a suspend +* and updates the software state as necessary. This function is also used +* for restoring the GPU after a GPU reset. +* +* Returns 0 on success, negative error code on failure. +*/ +static int amdgpu_device_ip_resume_phase3 (struct amdgpu_device *adev) +{ +int i, r; + +for (i =0 ; i < adev->num_ip_blocks; i++) { +if (!adev->ip_blocks[i].status.valid || adev->ip_blocks[i].status.hw) +continue ; +if (adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_DCE ) { + r = adev->ip_blocks[i].version->funcs->resume (adev); +if (r) +return r; + } + } + +return 0 ; +} + +/** * amdgpu_device_ip_resume - run resume for hardware IPs * * @adev: amdgpu_device pointer
@@ -3230,6 +3261,13 @@ static int amdgpu_device_ip_resume(struc r =amdgpu_device_ip_resume_phase2 (adev); +if (r) +return r; + +amdgpu_fence_driver_hw_init (adev); + + r =amdgpu_device_ip_resume_phase3 (adev); +return r; }
@@ -4229,7 +4267,6 @@ int amdgpu_device_resume(struct drm_devidev_err (adev->dev,"amdgpu_device_ip_resume failed (%d).\n" , r); goto exit; } -amdgpu_fence_driver_hw_init (adev); r =amdgpu_device_ip_late_init (adev);if (r)
@@ -4999,6 +5036,10 @@ int amdgpu_do_asic_reset(struct list_heaif (r) goto out; + r =amdgpu_device_ip_resume_phase3 (tmp_adev); +if (r) + goto out; +if (vram_lost)amdgpu_device_fill_reset_magic (tmp_adev);
Greg Kroah-Hartman
maintainerPATCH 349/356 ALSA: hda: Fix build error without CONFIG_SND_DEBUG
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 0ddf2784d6c29e59409a62b8f32dc5abe56135a4 upstream.
The macro should have been defined without setting the non-existing name field in the case of CONFIG_SND_DEBUG=n.
--- sound/pci/hda/hda_local.h | 6 ++++++ 1 file changed, 6 insertions(+)
sound/pci/hda/hda_local.h +6 -0
@@ -308,9 +308,15 @@ struct hda_quirk {#endif }; +#ifdef CONFIG_SND_DEBUG_VERBOSE #define HDA_CODEC_QUIRK (vend, dev, xname, val) \ { _SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname),\ .match_codec_ssid = true } +#else +#define HDA_CODEC_QUIRK (vend, dev, xname, val) \ + { _SND_PCI_QUIRK_ID(vend, dev), .value = (val), \ + .match_codec_ssid = true } +#endif struct snd_hda_pin_quirk {unsigned int codec;/* Codec vendor/device ID */
Greg Kroah-Hartman
maintainerPATCH 350/356 net/smc: fix incorrect SMC-D link group matching logic
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
commit c3dfcdb65ec1a4813ec1e0871c52c671ba9c71ac upstream.
The logic to determine if SMC-D link group matches is incorrect. The correct logic should be that it only returns true when the GID is the same, and the SMC-D device is the same and the extended GID is the same (in the case of virtual ISM).
It can be fixed by adding brackets around the conditional (or ternary) operator expression. But for better readability and maintainability, it has been changed to an if-else statement.
--- net/smc/smc_core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
net/smc/smc_core.c +9 -3
@@ -1889,9 +1889,15 @@ static bool smcd_lgr_match(struct smc_li struct smcd_dev *smcismdev, struct smcd_gid *peer_gid) { - return lgr->peer_gid.gid == peer_gid->gid && lgr->smcd == smcismdev && - smc_ism_is_virtual(smcismdev) ? - (lgr->peer_gid.gid_ext == peer_gid->gid_ext) : 1; +if (lgr->peer_gid.gid != peer_gid->gid || + lgr->smcd != smcismdev) +return false; + +if (smc_ism_is_virtual (smcismdev) && + lgr->peer_gid.gid_ext != peer_gid->gid_ext) +return false; + +return true; }/* create a new SMC connection (and a new link group if necessary) */
Greg Kroah-Hartman
maintainerPATCH 351/356 usb: dwc3: ep0: Dont reset resource alloc flag
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
commit f2e0eee4703869dc5edb5302a919861566ca7797 upstream.
The DWC3_EP_RESOURCE_ALLOCATED flag ensures that the resource of an endpoint is only assigned once. Unless the endpoint is reset, don't clear this flag. Otherwise we may set endpoint resource again, which prevents the driver from initiate transfer after handling a STALL or endpoint halt to the control endpoint.
--- drivers/usb/dwc3/ep0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/dwc3/ep0.c +2 -1
@@ -226,7 +226,8 @@ void dwc3_ep0_stall_and_restart(struct d/* reinitialize physical ep1 */ dep = dwc->eps[1 ]; - dep->flags =DWC3_EP_ENABLED ; + dep->flags &=DWC3_EP_RESOURCE_ALLOCATED ; + dep->flags |=DWC3_EP_ENABLED ;/* stall is always issued on EP0 */ dep = dwc->eps[0 ];
Greg Kroah-Hartman
maintainerPATCH 352/356 ALSA: usb-audio: Update UMP group attributes for GTB blocks, too
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit ebaa86c0bddd2c47c516bf2096b17c0bed71d914 upstream.
When a FB is created from a GTB instead of UMP FB Info inquiry, we missed the update of the corresponding UMP Group attributes. Export the call of updater and let it be called from the USB driver.
--- include/sound/ump.h | 1 + sound/core/ump.c | 9 +++++---- sound/usb/midi2.c | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-)
include/sound/ump.h +1 -0
@@ -122,6 +122,7 @@ static inline int snd_ump_attach_legacy_int snd_ump_receive_ump_val (struct snd_ump_endpoint *ump,u32 val);int snd_ump_switch_protocol (struct snd_ump_endpoint *ump,unsigned int protocol); +void snd_ump_update_group_attrs (struct snd_ump_endpoint *ump);/* * Some definitions for UMP
sound/core/ump.c +5 -4
@@ -525,7 +525,7 @@ static void snd_ump_proc_read(struct snd }/* update dir_bits and active flag for all groups in the client */ -static void update_group_attrs (struct snd_ump_endpoint *ump) +void snd_ump_update_group_attrs (struct snd_ump_endpoint *ump) {struct snd_ump_block *fb;struct snd_ump_group *group;
@@ -575,6 +575,7 @@ static void update_group_attrs(struct sn } } } +EXPORT_SYMBOL_GPL (snd_ump_update_group_attrs);/* * UMP endpoint and function block handling
@@ -848,7 +849,7 @@ static int ump_handle_fb_info_msg(structif (fb) {fill_fb_info (ump, &fb->info, buf);if (ump->parsed) { -update_group_attrs (ump); +snd_ump_update_group_attrs (ump);seq_notify_fb_change (ump, fb); } }
@@ -880,7 +881,7 @@ static int ump_handle_fb_name_msg(struct buf->raw, 3);/* notify the FB name update to sequencer, too */ if (ret >0 && ump->parsed) { -update_group_attrs (ump); +snd_ump_update_group_attrs (ump);seq_notify_fb_change (ump, fb); }return ret;
@@ -1055,7 +1056,7 @@ int snd_ump_parse_endpoint(struct snd_um }/* initialize group attributions */ -update_group_attrs (ump); +snd_ump_update_group_attrs (ump); error: ump->parsed = true;
sound/usb/midi2.c +2 -0
@@ -873,6 +873,8 @@ static int create_gtb_block(struct snd_u fb->info.flags |=SNDRV_UMP_BLOCK_IS_MIDI1 |SNDRV_UMP_BLOCK_IS_LOWSPEED ; +snd_ump_update_group_attrs (rmidi->ump); +usb_audio_dbg (umidi->chip,"Created a UMP block %d from GTB, name=%s\n" , blk, fb->info.name);
Greg Kroah-Hartman
maintainerPATCH 353/356 platform/x86: asus-wmi: Fix thermal profile initialization
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
commit b012170fed282151f7ba8988a347670c299f5ab3 upstream.
When support for vivobook fan profiles was added, the initial call to throttle_thermal_policy_set_default() was removed, which however is necessary for full initialization.
Fix this by calling throttle_thermal_policy_set_default() again when setting up the platform profile.
--- drivers/platform/x86/asus-wmi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/platform/x86/asus-wmi.c +10 -0
@@ -3569,6 +3569,16 @@ static int platform_profile_setup(structif (!asus->throttle_thermal_policy_dev)return 0 ; +/* +* We need to set the default thermal profile during probe or otherwise +* the system will often remain in silent mode, causing low performance. +*/ + err =throttle_thermal_policy_set_default (asus); +if (err <0 ) { +pr_warn ("Failed to set default thermal profile\n" ); +return err; + } +dev_info (dev,"Using throttle_thermal_policy for platform_profile support\n" ); asus->platform_profile_handler.profile_get = asus_wmi_platform_profile_get;
Greg Kroah-Hartman
maintainerPATCH 354/356 serial: amba-pl011: fix build regression
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit b5a23a60e8ab5711f4952912424347bf3864ce8d upstream.
When CONFIG_DMA_ENGINE is disabled, the driver now fails to build:
drivers/tty/serial/amba-pl011.c: In function 'pl011_unthrottle_rx':drivers/tty/serial/amba-pl011.c:1822:16: error: 'struct uart_amba_port' has no member named 'using_rx_dma'
1822 | if (uap->using_rx_dma) {
| ^~drivers/tty/serial/amba-pl011.c:1823:20: error: 'struct uart_amba_port' has no member named 'dmacr'
1823 | uap->dmacr |= UART011_RXDMAE;
| ^~drivers/tty/serial/amba-pl011.c:1824:32: error: 'struct uart_amba_port' has no member named 'dmacr'
1824 | pl011_write(uap->dmacr, uap, REG_DMACR);
| ^~
Add the missing #ifdef check around these field accesses, matching what other parts of this driver do.
--- drivers/tty/serial/amba-pl011.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/serial/amba-pl011.c +2 -0
@@ -1837,10 +1837,12 @@ static void pl011_unthrottle_rx(struct upl011_write (uap->im, uap,REG_IMSC ); +#ifdef CONFIG_DMA_ENGINE if (uap->using_rx_dma) { uap->dmacr |=UART011_RXDMAE ;pl011_write (uap->dmacr, uap,REG_DMACR ); } +#endif uart_port_unlock_irqrestore (&uap->port, flags); }
Greg Kroah-Hartman
maintainerPATCH 355/356 i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 36faa04ce3d9c962b4b29d285ad07ca29e2988e4 upstream.
When a new device hotjoins, a new dynamic address is assigned. i3c_master_add_i3c_dev_locked() identifies that the device was previously attached to the bus and locates the olddev.
i3c_master_add_i3c_dev_locked()
{
...
olddev = i3c_master_search_i3c_dev_duplicate(newdev);
...
if (olddev) {
...
i3c_dev_disable_ibi_locked(olddev);
^^^^^^
The olddev should not receive any commands on the i3c bus as it
does not exist and has been assigned a new address. This will
result in NACK or timeout. So remove it.
}
i3c_dev_free_ibi_locked(olddev);
^^^^^^^^
This function internally calls i3c_dev_disable_ibi_locked() function
causing to send DISEC command with old Address.
The olddev should not receive any commands on the i3c bus as it
does not exist and has been assigned a new address. This will
result in NACK or timeout. So, update the olddev->ibi->enabled
flag to false to avoid DISEC with OldAddr.
}Include part of Ravindra Yashvant Shinde's work:
https://lore.kernel.org/linux-i3c/[email protected]/T/#u
--- drivers/i3c/master.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/i3c/master.c +9 -4
@@ -2048,11 +2048,16 @@ int i3c_master_add_i3c_dev_locked(struct ibireq.max_payload_len = olddev->ibi->max_payload_len; ibireq.num_slots = olddev->ibi->num_slots; -if (olddev->ibi->enabled) { +if (olddev->ibi->enabled) enable_ibi = true; -i3c_dev_disable_ibi_locked (olddev); - } - +/* +* The olddev should not receive any commands on the +* i3c bus as it does not exist and has been assigned +* a new address. This will result in NACK or timeout. +* So, update the olddev->ibi->enabled flag to false +* to avoid DISEC with OldAddr. +*/ + olddev->ibi->enabled = false;i3c_dev_free_ibi_locked (olddev); }mutex_unlock (&olddev->ibi_lock);
Greg Kroah-Hartman
maintainerPATCH 356/356 i3c: master: svc: fix possible assignment of the same address to two devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 3b2ac810d86eb96e882db80a3320a3848b133208 upstream.
svc_i3c_master_do_daa() {
...
for (i = 0; i < dev_nb; i++) {
ret = i3c_master_add_i3c_dev_locked(m, addrs[i]);
if (ret)
goto rpm_out;
}
}If two devices (A and B) are detected in DAA and address 0xa is assigned to device A and 0xb to device B, a failure in i3c_master_add_i3c_dev_locked() for device A (addr: 0xa) could prevent device B (addr: 0xb) from being registered on the bus. The I3C stack might still consider 0xb a free address. If a subsequent Hotjoin occurs, 0xb might be assigned to Device A, causing both devices A and B to use the same address 0xb, violating the I3C specification.
The return value for i3c_master_add_i3c_dev_locked() should not be checked because subsequent steps will scan the entire I3C bus, independent of whether i3c_master_add_i3c_dev_locked() returns success.
If device A registration fails, there is still a chance to register device B. i3c_master_add_i3c_dev_locked() can reset DAA if a failure occurs while retrieving device information.
--- drivers/i3c/master/svc-i3c-master.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)
drivers/i3c/master/svc-i3c-master.c +21 -6
@@ -1018,12 +1018,27 @@ static int svc_i3c_master_do_daa(struct goto rpm_out; } -/* Register all devices who participated to the core */ -for (i =0 ; i < dev_nb; i++) { - ret =i3c_master_add_i3c_dev_locked (m, addrs[i]); -if (ret) - goto rpm_out; - } +/* +* Register all devices who participated to the core +* +* If two devices (A and B) are detected in DAA and address 0xa is assigned to +* device A and 0xb to device B, a failure in i3c_master_add_i3c_dev_locked() +* for device A (addr: 0xa) could prevent device B (addr: 0xb) from being +* registered on the bus. The I3C stack might still consider 0xb a free +* address. If a subsequent Hotjoin occurs, 0xb might be assigned to Device A, +* causing both devices A and B to use the same address 0xb, violating the I3C +* specification. +* +* The return value for i3c_master_add_i3c_dev_locked() should not be checked +* because subsequent steps will scan the entire I3C bus, independent of +* whether i3c_master_add_i3c_dev_locked() returns success. +* +* If device A registration fails, there is still a chance to register device +* B. i3c_master_add_i3c_dev_locked() can reset DAA if a failure occurs while +* retrieving device information. +*/ +for (i =0 ; i < dev_nb; i++) +i3c_master_add_i3c_dev_locked (m, addrs[i]);/* Configure IBI auto-rules */ ret =svc_i3c_update_ibirules (master);
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Am 12.12.2024 um 15:55 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
No new regressions for Tegra ...
Test results for stable-v6.6:
10 builds: 10 pass, 0 fail
26 boots: 26 pass, 0 fail
116 tests: 115 pass, 1 failLinux version: 6.6.66-rc1-gae86bb742fa8
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Test failures: tegra186-p2771-0000: pm-system-suspend.sh
Tegra186 tests are failing randomly but there is a fix now in the mainline ...
4c49f38e20a5 ("net: stmmac: fix TSO DMA API usage causing oops")
Let me know if you want me to send a separate request to include in this in stable.
Otherwise ...
Thanks
Jon
Signature · 1 line
nvpublic
Greg Kroah-Hartman
maintainerQuoted 37 lines · Jon Hunter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
No new regressions for Tegra ...
Test results for stable-v6.6:
10 builds: 10 pass, 0 fail 26 boots: 26 pass, 0 fail 116 tests: 115 pass, 1 failLinux version: 6.6.66-rc1-gae86bb742fa8
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04Test failures: tegra186-p2771-0000:
pm-system-suspend.sh
Quoted 7 lines
Tegra186 tests are failing randomly but there is a fix now in the mainline
...
4c49f38e20a5("net: stmmac: fix TSO DMA API usage causing oops")Let me know if you want me to send a separate request to include in this in stable.
Please do, so it doesn't get lost.
thanks,
greg k-h
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.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: 6.6.66-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: ae86bb742fa81e7826a49817e016bf288015f456
* git describe: v6.6.65-357-gae86bb742fa8
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.6.y/build/v6.6.65-357-gae86bb742fa8
## Test Regressions (compared to v6.6.63-677-g1415e716e528)
## Metric Regressions (compared to v6.6.63-677-g1415e716e528)
## Test Fixes (compared to v6.6.63-677-g1415e716e528)
## Metric Fixes (compared to v6.6.63-677-g1415e716e528)
## Test result summary
total: 130339, pass: 106681, fail: 3098, skip: 20494, xfail: 66
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 128 total, 128 passed, 0 failed
* arm64: 40 total, 40 passed, 0 failed
* i386: 27 total, 25 passed, 2 failed
* mips: 26 total, 25 passed, 1 failed
* parisc: 4 total, 4 passed, 0 failed
* powerpc: 32 total, 31 passed, 1 failed
* riscv: 19 total, 19 passed, 0 failed
* s390: 14 total, 13 passed, 1 failed
* sh: 10 total, 10 passed, 0 failed
* sparc: 7 total, 7 passed, 0 failed
* x86_64: 32 total, 32 passed, 0 failed
## Test suites summary
* boot
* commands
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-efivarfs
* kselftest-exec
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-filesystems-epoll
* kselftest-firmware
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-kcmp
* kselftest-kvm
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-mincore
* kselftest-mqueue
* kselftest-net
* kselftest-net-mptcp
* kselftest-openat2
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-tc-testing
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user_events
* kselftest-vDSO
* kselftest-x86
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-build-clang
* log-parser-build-gcc
* log-parser-test
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-hugetlb
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-pty
* ltp-sched
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* perf
* rcutorture
--
Linaro LKFT
https://lkft.linaro.org
Thanks,
Hardik
The kernel, bpf tool, amd kselftest tool builds fine for v6.6.66-rc1 on x86 and arm64 Azure VM.
Thanks,
Hardik
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Hello,
Quoted 7 lines · On Thu, 12 Dec 2024 15:55:19 +0100 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +0000. Anything received after that time might be too late.
This rc kernel passes DAMON functionality test[1] on my test machine. Attaching the test results summary below. Please note that I retrieved the kernel from linux-stable-rc tree[2].
[1] https://github.com/damonitor/damon-tests/tree/next/corr
[2] f5d2f18aeac4 ("Linux 6.6.66-rc1")
Thanks,
SJ
[...]
---
ok 1 selftests: damon: debugfs_attrs.sh
ok 2 selftests: damon: debugfs_schemes.sh
ok 3 selftests: damon: debugfs_target_ids.sh
ok 4 selftests: damon: debugfs_empty_targets.sh
ok 5 selftests: damon: debugfs_huge_count_read_write.sh
ok 6 selftests: damon: debugfs_duplicate_context_creation.sh
ok 7 selftests: damon: debugfs_rm_non_contexts.sh
ok 8 selftests: damon: sysfs.sh
ok 9 selftests: damon: sysfs_update_removed_scheme_dir.sh
ok 10 selftests: damon: reclaim.sh
ok 11 selftests: damon: lru_sort.sh
ok 1 selftests: damon-tests: kunit.sh
ok 2 selftests: damon-tests: huge_count_read_write.sh
ok 3 selftests: damon-tests: buffer_overflow.sh
ok 4 selftests: damon-tests: rm_contexts.sh
ok 5 selftests: damon-tests: record_null_deref.sh
ok 6 selftests: damon-tests: dbgfs_target_ids_read_before_terminate_race.sh ok 7 selftests: damon-tests: dbgfs_target_ids_pid_leak.sh
ok 8 selftests: damon-tests: damo_tests.sh
ok 9 selftests: damon-tests: masim-record.sh
ok 10 selftests: damon-tests: build_i386.sh
ok 11 selftests: damon-tests: build_arm64.sh # SKIP
ok 12 selftests: damon-tests: build_m68k.sh # SKIP
ok 13 selftests: damon-tests: build_i386_idle_flag.sh
ok 14 selftests: damon-tests: build_i386_highpte.sh
ok 15 selftests: damon-tests: build_nomemcg.sh
[33m
[92mPASS [39m
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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/v6.x/stable-review/patch-6.6.66-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
OVERVIEW
Builds: 23 passed, 0 failed
Boot tests: 210 passed, 0 failed
CI systems: maestro
REVISION
Commit
name: v6.6.65-357-gae86bb742fa8
hash: ae86bb742fa81e7826a49817e016bf288015f456
Checked out from
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.yBUILDS
No build failures found
BOOT TESTS
No failures found
See complete and up-to-date report at:
https://kcidb.kernelci.org/d/revision/revision?orgId=1&var-git_commit_hash=ae86bb742fa81e7826a49817e016bf288015f456&var-patchset_hash=
Thanks,
KernelCI team
Hi Greg,
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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.
No problems seen on x86_64 and aarch64 with our testing.
Thanks,
Harshit