mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 38 participants
  • 18135 discussions
[PATCH openEuler-1.0-LTS] media: em28xx: initialize refcount before kref_get
by Yongqiang Liu 27 Sep '22

27 Sep '22
From: Dongliang Mu <mudongliangabcd(a)gmail.com> stable inclusion from stable-v4.19.238 commit 0113fa98a49a8e46a19b0ad80f29c904c6feec23 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5RX5X CVE: CVE-2022-3239 --------------------------- [ Upstream commit c08eadca1bdfa099e20a32f8fa4b52b2f672236d ] The commit 47677e51e2a4("[media] em28xx: Only deallocate struct em28xx after finishing all extensions") adds kref_get to many init functions (e.g., em28xx_audio_init). However, kref_init is called too late in em28xx_usb_probe, since em28xx_init_dev before will invoke those init functions and call kref_get function. Then refcount bug occurs in my local syzkaller instance. Fix it by moving kref_init before em28xx_init_dev. This issue occurs not only in dev but also dev->dev_next. Fixes: 47677e51e2a4 ("[media] em28xx: Only deallocate struct em28xx after finishing all extensions") Reported-by: syzkaller <syzkaller(a)googlegroups.com> Signed-off-by: Dongliang Mu <mudongliangabcd(a)gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Guo Mengqi <guomengqi3(a)huawei.com> Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com> Reviewed-by: Weilong Chen <chenweilong(a)huawei.com> Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com> --- drivers/media/usb/em28xx/em28xx-cards.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 3f59a98dbf9a..00a3b5768b9a 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3816,6 +3816,8 @@ static int em28xx_usb_probe(struct usb_interface *intf, goto err_free; } + kref_init(&dev->ref); + dev->devno = nr; dev->model = id->driver_info; dev->alt = -1; @@ -3916,6 +3918,8 @@ static int em28xx_usb_probe(struct usb_interface *intf, } if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) { + kref_init(&dev->dev_next->ref); + dev->dev_next->ts = SECONDARY_TS; dev->dev_next->alt = -1; dev->dev_next->is_audio_only = has_vendor_audio && @@ -3970,12 +3974,8 @@ static int em28xx_usb_probe(struct usb_interface *intf, em28xx_write_reg(dev, 0x0b, 0x82); mdelay(100); } - - kref_init(&dev->dev_next->ref); } - kref_init(&dev->ref); - request_modules(dev); /* -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS 1/6] efi: capsule-loader: Fix use-after-free in efi_capsule_write
by Yongqiang Liu 26 Sep '22

26 Sep '22
From: Hyunwoo Kim <imv4bel(a)gmail.com> mainline inclusion from mainline-v6.0-rc5 commit 9cb636b5f6a8cc6d1b50809ec8f8d33ae0c84c95 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5QI0W CVE: CVE-2022-40307 --------------------------- A race condition may occur if the user calls close() on another thread during a write() operation on the device node of the efi capsule. This is a race condition that occurs between the efi_capsule_write() and efi_capsule_flush() functions of efi_capsule_fops, which ultimately results in UAF. So, the page freeing process is modified to be done in efi_capsule_release() instead of efi_capsule_flush(). Cc: <stable(a)vger.kernel.org> # v4.9+ Signed-off-by: Hyunwoo Kim <imv4bel(a)gmail.com> Link: https://lore.kernel.org/all/20220907102920.GA88602@ubuntu/ Signed-off-by: Ard Biesheuvel <ardb(a)kernel.org> Signed-off-by: Xia Longlong <xialonglong1(a)huawei.com> Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com> Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com> Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com> --- drivers/firmware/efi/capsule-loader.c | 31 ++++++--------------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index 96688986da56..94aae1e67c99 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -243,29 +243,6 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, return ret; } -/** - * efi_capsule_flush - called by file close or file flush - * @file: file pointer - * @id: not used - * - * If a capsule is being partially uploaded then calling this function - * will be treated as upload termination and will free those completed - * buffer pages and -ECANCELED will be returned. - **/ -static int efi_capsule_flush(struct file *file, fl_owner_t id) -{ - int ret = 0; - struct capsule_info *cap_info = file->private_data; - - if (cap_info->index > 0) { - pr_err("capsule upload not complete\n"); - efi_free_all_buff_pages(cap_info); - ret = -ECANCELED; - } - - return ret; -} - /** * efi_capsule_release - called by file close * @inode: not used @@ -278,6 +255,13 @@ static int efi_capsule_release(struct inode *inode, struct file *file) { struct capsule_info *cap_info = file->private_data; + if (cap_info->index > 0 && + (cap_info->header.headersize == 0 || + cap_info->count < cap_info->total_size)) { + pr_err("capsule upload not complete\n"); + efi_free_all_buff_pages(cap_info); + } + kfree(cap_info->pages); kfree(cap_info->phys); kfree(file->private_data); @@ -325,7 +309,6 @@ static const struct file_operations efi_capsule_fops = { .owner = THIS_MODULE, .open = efi_capsule_open, .write = efi_capsule_write, - .flush = efi_capsule_flush, .release = efi_capsule_release, .llseek = no_llseek, }; -- 2.25.1
1 5
0 0
[PATCH] Memory model: Fix the memory model issues for Linux kernel
by Hanjun Guo 24 Sep '22

24 Sep '22
From: Jonas Oberhauser <jonas.oberhauser(a)huawei.com> This is the update and fixes for memory model, simplify the model by removing redundancies, making semantics of seq-cst explicit, making ppo a subset of po, making ppo locally computable, as well as eliminating several spurious bugs in qspinlock and litmus tests, and ensuring correct compilation to the official power model. These issues were detected by Jonas Oberhauser, Viktor Vafeiadis, and the authors of "Verifying and Optimizing Compact NUMA-Aware Locks on Weak Memory Models", and the solutions are proposed by Jonas Oberhauser and Viktor Vafeiadis. Please refer to this link on the web: https://static.sched.com/hosted_files/osseu2022/e1/oss-eu22-jonas.pdf Signed-off-by: Jonas Oberhauser <jonas.oberhauser(a)huawei.com> Signed-off-by: Hanjun Guo <guohanjun(a)huawei.com> --- tools/memory-model/linux-kernel.bell | 9 ++-- tools/memory-model/linux-kernel.cat | 100 +++++++++++++++++++---------------- tools/memory-model/linux-kernel.def | 34 ++++++------ 3 files changed, 77 insertions(+), 66 deletions(-) diff --git a/tools/memory-model/linux-kernel.bell b/tools/memory-model/linux-kernel.bell index 5be86b1..880b28b 100644 --- a/tools/memory-model/linux-kernel.bell +++ b/tools/memory-model/linux-kernel.bell @@ -4,6 +4,8 @@ * Copyright (C) 2016 Luc Maranget <luc.maranget(a)inria.fr> for Inria * Copyright (C) 2017 Alan Stern <stern(a)rowland.harvard.edu>, * Andrea Parri <parri.andrea(a)gmail.com> + * Copyright (C) 2022 Jonas Oberhauser <jonas.oberhauser(a)huawei.com> + * Viktor Vafeiadis <viktor(a)mpi-sws.org> * * An earlier version of this file appeared in the companion webpage for * "Frightening small children and disconcerting grown-ups: Concurrency @@ -16,10 +18,11 @@ enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) || 'release (*smp_store_release*) || 'acquire (*smp_load_acquire*) || + 'seq-cst (*smp_load, xchg...*) || 'noreturn (* R of non-return RMW *) -instructions R[{'once,'acquire,'noreturn}] -instructions W[{'once,'release}] -instructions RMW[{'once,'acquire,'release}] +instructions R[{'seq-cst, 'once,'acquire,'noreturn}] +instructions W[{'seq-cst, 'once,'release}] +instructions RMW[{'seq-cst, 'once,'acquire,'release}] enum Barriers = 'wmb (*smp_wmb*) || 'rmb (*smp_rmb*) || diff --git a/tools/memory-model/linux-kernel.cat b/tools/memory-model/linux-kernel.cat index d70315f..9f14d31 100644 --- a/tools/memory-model/linux-kernel.cat +++ b/tools/memory-model/linux-kernel.cat @@ -4,6 +4,8 @@ * Copyright (C) 2016 Luc Maranget <luc.maranget(a)inria.fr> for Inria * Copyright (C) 2017 Alan Stern <stern(a)rowland.harvard.edu>, * Andrea Parri <parri.andrea(a)gmail.com> + * Copyright (C) 2022 Jonas Oberhauser <jonas.oberhauser(a)huawei.com>, + * Viktor Vafeiadis <viktor(a)mpi-sws.org> * * An earlier version of this file appeared in the companion webpage for * "Frightening small children and disconcerting grown-ups: Concurrency @@ -25,25 +27,33 @@ include "lock.cat" (*******************) (* Release Acquire *) + let acq-po = [Acquire] ; po ; [M] let po-rel = [M] ; po ; [Release] let po-unlock-lock-po = po ; [UL] ; (po|rf) ; [LKR] ; po (* Fences *) -let R4rmb = R \ Noreturn (* Reads for which rmb works *) -let rmb = [R4rmb] ; fencerel(Rmb) ; [R4rmb] -let wmb = [W] ; fencerel(Wmb) ; [W] -let mb = ([M] ; fencerel(Mb) ; [M]) | - ([M] ; fencerel(Before-atomic) ; [RMW] ; po? ; [M]) | - ([M] ; po? ; [RMW] ; fencerel(After-atomic) ; [M]) | - ([M] ; po? ; [LKW] ; fencerel(After-spinlock) ; [M]) | - ([M] ; po ; [UL] ; (co | po) ; [LKW] ; - fencerel(After-unlock-lock) ; [M]) -let gp = po ; [Sync-rcu | Sync-srcu] ; po? -let strong-fence = mb | gp - +let R4rmb = R \ Noreturn +let rmb = [R4rmb] ; po ; [Rmb] ; po ; [R4rmb] +let wmb = [W] ; po ; [Wmb] ; po ; [W] + +let rmb-plain = [R \ Noreturn] ; po ; [Rmb] ; po \ ( po ; [W] ; po-loc) ; [R \ Noreturn] +let plain-wmb = [W] ; po \ (po-loc ; [W] ; po) ; [Wmb] ; po ; [W] +let strong-fence = + [M] ; po ; [Mb] ; po ; [M] + | [M] ; po ; [Before-atomic] ; po ; [RMW] ; po? ; [M] + | [M] ; po? ; [RMW] ; po ; [After-atomic] ; po ; [M] + | [M] ; po? ; [LKW] ; po ; [After-spinlock] ; po ; [M] + | [M] ; po ; [UL] ; po ; [LKR] ; po ; [After-unlock-lock] ; po ; [M] + | [M] ; po? ; [SC] ; po ; [M] + | [M] ; po ; [SC] ; po? ; [M] + | po ; [Sync-rcu | Sync-srcu] ; po? +let strong-sync = strong-fence + | ([M] ; po-unlock-lock-po ; [After-unlock-lock] ; po ; [M]) let nonrw-fence = strong-fence | po-rel | acq-po let fence = nonrw-fence | wmb | rmb + + let barrier = fencerel(Barrier | Rmb | Wmb | Mb | Sync-rcu | Sync-srcu | Before-atomic | After-atomic | Acquire | Release | Rcu-lock | Rcu-unlock | Srcu-lock | Srcu-unlock) | @@ -64,35 +74,33 @@ empty rmw & (fre ; coe) as atomic (* Instruction execution ordering *) (**********************************) + (* Preserved Program Order *) -let dep = addr | data -let rwdep = (dep | ctrl) ; [W] -let overwrite = co | fr -let to-w = rwdep | (overwrite & int) | (addr ; [Plain] ; wmb) -let to-r = addr | (dep ; [Marked] ; rfi) -let ppo = to-r | to-w | fence | (po-unlock-lock-po & int) +let dop = rmb-plain? ; (addr | data | ctrl | rfi)+; plain-wmb? +let to-w = (dop | po-loc) ; [W] +let lrs = ([W] ; po-loc ; [R]) \ (po-loc ; [W] ; po-loc) +let to-r = addr | ((addr | data) ; lrs) +let ppo = to-r | to-w | fence | (po ; [UL] ; po ; [LKR] ; po) (* Propagation: Ordering from release operations and strong fences. *) -let A-cumul(r) = (rfe ; [Marked])? ; r -let cumul-fence = [Marked] ; (A-cumul(strong-fence | po-rel) | wmb | - po-unlock-lock-po) ; [Marked] -let prop = [Marked] ; (overwrite & ext)? ; cumul-fence* ; - [Marked] ; rfe? ; [Marked] +let cumul-fence = [Marked] ; (rfe? ; (po-rel ; (rfe ; rmw)*) | wmb | po-unlock-lock-po) ; [Marked] +let prop = [Marked] ; ((co | fr) & ext) ; cumul-fence* ; [Marked] ; rfe? ; [Marked] + (* * Happens Before: Ordering from the passage of time. - * No fences needed here for prop because relation confined to one process. *) -let hb = [Marked] ; (ppo | rfe | ((prop \ id) & int)) ; [Marked] -acyclic hb as happens-before +let hb = [Marked] ; (ppo | rfe | prop ; strong-sync) ; [Marked] +acyclic hb + +(* No fences needed here for prop because relation confined to one process. *) +irreflexive (prop ; ppo*) + + + + -(****************************************) -(* Write and fence propagation ordering *) -(****************************************) -(* Propagation: Each non-rf link needs a strong fence. *) -let pb = prop ; strong-fence ; hb* ; [Marked] -acyclic pb as propagation (*******) (* RCU *) @@ -118,7 +126,7 @@ let srcu-rscsi = srcu-rscs^-1 * one but two non-rf relations, but only in conjunction with an RCU * read-side critical section. *) -let rcu-link = po? ; hb* ; pb* ; prop ; po +let rcu-link = po? ; hb* ; prop? ; po (* * Any sequence containing at least as many grace periods as RCU read-side @@ -139,20 +147,20 @@ let rec rcu-order = rcu-gp | srcu-gp | ((srcu-rscsi ; rcu-link ; rcu-order ; rcu-link ; srcu-gp) & loc) | (rcu-order ; rcu-link ; rcu-order) let rcu-fence = po ; rcu-order ; po? -let fence = fence | rcu-fence -let strong-fence = strong-fence | rcu-fence +let fence-rcu = fence | rcu-fence +let strong-sync-rcu = strong-sync | rcu-fence -(* rb orders instructions just as pb does *) -let rb = prop ; rcu-fence ; hb* ; pb* ; [Marked] +(* rb orders instructions just as hb does *) +let rb = prop? ; rcu-fence ; hb* ; [Marked] irreflexive rb as rcu (* - * The happens-before, propagation, and rcu constraints are all + * The happens-before and rcu constraints are all * expressions of temporal ordering. They could be replaced by * a single constraint on an "executes-before" relation, xb: * - * let xb = hb | pb | rb + * let xb = hb | rb * acyclic xb as executes-before *) @@ -166,24 +174,24 @@ let mixed-accesses = ([Plain & W] ; (po-loc \ barrier) ; [Marked]) | flag ~empty mixed-accesses as mixed-accesses (* Executes-before and visibility *) -let xbstar = (hb | pb | rb)* +let xbstar = (hb | rb)* let vis = cumul-fence* ; rfe? ; [Marked] ; - ((strong-fence ; [Marked] ; xbstar) | (xbstar & int)) + ((strong-sync-rcu ; [Marked] ; xbstar) | (xbstar & int)) (* Boundaries for lifetimes of plain accesses *) -let w-pre-bounded = [Marked] ; (addr | fence)? +let w-pre-bounded = [Marked] ; (addr | fence-rcu)? let r-pre-bounded = [Marked] ; (addr | nonrw-fence | ([R4rmb] ; fencerel(Rmb) ; [~Noreturn]))? -let w-post-bounded = fence? ; [Marked] +let w-post-bounded = fence-rcu? ; [Marked] let r-post-bounded = (nonrw-fence | ([~Noreturn] ; fencerel(Rmb) ; [R4rmb]))? ; [Marked] (* Visibility and executes-before for plain accesses *) -let ww-vis = fence | (strong-fence ; xbstar ; w-pre-bounded) | +let ww-vis = (strong-sync-rcu ; xbstar ; w-pre-bounded) | (w-post-bounded ; vis ; w-pre-bounded) -let wr-vis = fence | (strong-fence ; xbstar ; r-pre-bounded) | +let wr-vis = (strong-sync-rcu ; xbstar ; r-pre-bounded) | (w-post-bounded ; vis ; r-pre-bounded) -let rw-xbstar = fence | (r-post-bounded ; xbstar ; w-pre-bounded) +let rw-xbstar = (r-post-bounded ; xbstar ; w-pre-bounded) (* Potential races *) let pre-race = ext & ((Plain * M) | ((M \ IW) * Plain)) diff --git a/tools/memory-model/linux-kernel.def b/tools/memory-model/linux-kernel.def index ef0f3c1..df239c2 100644 --- a/tools/memory-model/linux-kernel.def +++ b/tools/memory-model/linux-kernel.def @@ -14,7 +14,7 @@ smp_store_release(X,V) { __store{release}(*X,V); } smp_load_acquire(X) __load{acquire}(*X) rcu_assign_pointer(X,V) { __store{release}(X,V); } rcu_dereference(X) __load{once}(X) -smp_store_mb(X,V) { __store{once}(X,V); __fence{mb}; } +smp_store_mb(X,V) { __store{seq-cst}(X,V); } // Fences smp_mb() { __fence{mb}; } @@ -27,11 +27,11 @@ smp_mb__after_unlock_lock() { __fence{after-unlock-lock}; } barrier() { __fence{barrier}; } // Exchange -xchg(X,V) __xchg{mb}(X,V) +xchg(X,V) __xchg{seq-cst}(X,V) xchg_relaxed(X,V) __xchg{once}(X,V) xchg_release(X,V) __xchg{release}(X,V) xchg_acquire(X,V) __xchg{acquire}(X,V) -cmpxchg(X,V,W) __cmpxchg{mb}(X,V,W) +cmpxchg(X,V,W) __cmpxchg{seq-cst}(X,V,W) cmpxchg_relaxed(X,V,W) __cmpxchg{once}(X,V,W) cmpxchg_acquire(X,V,W) __cmpxchg{acquire}(X,V,W) cmpxchg_release(X,V,W) __cmpxchg{release}(X,V,W) @@ -65,52 +65,52 @@ atomic_sub(V,X) { __atomic_op(X,-,V); } atomic_inc(X) { __atomic_op(X,+,1); } atomic_dec(X) { __atomic_op(X,-,1); } -atomic_add_return(V,X) __atomic_op_return{mb}(X,+,V) +atomic_add_return(V,X) __atomic_op_return{seq-cst}(X,+,V) atomic_add_return_relaxed(V,X) __atomic_op_return{once}(X,+,V) atomic_add_return_acquire(V,X) __atomic_op_return{acquire}(X,+,V) atomic_add_return_release(V,X) __atomic_op_return{release}(X,+,V) -atomic_fetch_add(V,X) __atomic_fetch_op{mb}(X,+,V) +atomic_fetch_add(V,X) __atomic_fetch_op{seq-cst}(X,+,V) atomic_fetch_add_relaxed(V,X) __atomic_fetch_op{once}(X,+,V) atomic_fetch_add_acquire(V,X) __atomic_fetch_op{acquire}(X,+,V) atomic_fetch_add_release(V,X) __atomic_fetch_op{release}(X,+,V) -atomic_inc_return(X) __atomic_op_return{mb}(X,+,1) +atomic_inc_return(X) __atomic_op_return{seq-cst}(X,+,1) atomic_inc_return_relaxed(X) __atomic_op_return{once}(X,+,1) atomic_inc_return_acquire(X) __atomic_op_return{acquire}(X,+,1) atomic_inc_return_release(X) __atomic_op_return{release}(X,+,1) -atomic_fetch_inc(X) __atomic_fetch_op{mb}(X,+,1) +atomic_fetch_inc(X) __atomic_fetch_op{seq-cst}(X,+,1) atomic_fetch_inc_relaxed(X) __atomic_fetch_op{once}(X,+,1) atomic_fetch_inc_acquire(X) __atomic_fetch_op{acquire}(X,+,1) atomic_fetch_inc_release(X) __atomic_fetch_op{release}(X,+,1) -atomic_sub_return(V,X) __atomic_op_return{mb}(X,-,V) +atomic_sub_return(V,X) __atomic_op_return{seq-cst}(X,-,V) atomic_sub_return_relaxed(V,X) __atomic_op_return{once}(X,-,V) atomic_sub_return_acquire(V,X) __atomic_op_return{acquire}(X,-,V) atomic_sub_return_release(V,X) __atomic_op_return{release}(X,-,V) -atomic_fetch_sub(V,X) __atomic_fetch_op{mb}(X,-,V) +atomic_fetch_sub(V,X) __atomic_fetch_op{seq-cst}(X,-,V) atomic_fetch_sub_relaxed(V,X) __atomic_fetch_op{once}(X,-,V) atomic_fetch_sub_acquire(V,X) __atomic_fetch_op{acquire}(X,-,V) atomic_fetch_sub_release(V,X) __atomic_fetch_op{release}(X,-,V) -atomic_dec_return(X) __atomic_op_return{mb}(X,-,1) +atomic_dec_return(X) __atomic_op_return{seq-cst}(X,-,1) atomic_dec_return_relaxed(X) __atomic_op_return{once}(X,-,1) atomic_dec_return_acquire(X) __atomic_op_return{acquire}(X,-,1) atomic_dec_return_release(X) __atomic_op_return{release}(X,-,1) -atomic_fetch_dec(X) __atomic_fetch_op{mb}(X,-,1) +atomic_fetch_dec(X) __atomic_fetch_op{seq-cst}(X,-,1) atomic_fetch_dec_relaxed(X) __atomic_fetch_op{once}(X,-,1) atomic_fetch_dec_acquire(X) __atomic_fetch_op{acquire}(X,-,1) atomic_fetch_dec_release(X) __atomic_fetch_op{release}(X,-,1) -atomic_xchg(X,V) __xchg{mb}(X,V) +atomic_xchg(X,V) __xchg{seq-cst}(X,V) atomic_xchg_relaxed(X,V) __xchg{once}(X,V) atomic_xchg_release(X,V) __xchg{release}(X,V) atomic_xchg_acquire(X,V) __xchg{acquire}(X,V) -atomic_cmpxchg(X,V,W) __cmpxchg{mb}(X,V,W) +atomic_cmpxchg(X,V,W) __cmpxchg{seq-cst}(X,V,W) atomic_cmpxchg_relaxed(X,V,W) __cmpxchg{once}(X,V,W) atomic_cmpxchg_acquire(X,V,W) __cmpxchg{acquire}(X,V,W) atomic_cmpxchg_release(X,V,W) __cmpxchg{release}(X,V,W) -atomic_sub_and_test(V,X) __atomic_op_return{mb}(X,-,V) == 0 -atomic_dec_and_test(X) __atomic_op_return{mb}(X,-,1) == 0 -atomic_inc_and_test(X) __atomic_op_return{mb}(X,+,1) == 0 -atomic_add_negative(V,X) __atomic_op_return{mb}(X,+,V) < 0 +atomic_sub_and_test(V,X) __atomic_op_return{seq-cst}(X,-,V) == 0 +atomic_dec_and_test(X) __atomic_op_return{seq-cst}(X,-,1) == 0 +atomic_inc_and_test(X) __atomic_op_return{seq-cst}(X,+,1) == 0 +atomic_add_negative(V,X) __atomic_op_return{seq-cst}(X,+,V) < 0 -- 1.7.12.4
1 0
0 0
[PATCH openEuler-1.0-LTS 1/4] mm: mem_reliable: Start fallback if no suitable zone found
by Yongqiang Liu 24 Sep '22

24 Sep '22
From: Ma Wupeng <mawupeng1(a)huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4SK3S CVE: NA -------------------------------- For reliable memory allocation bind to nodes which do not hvve any reliable zones, its memory allocation will fail and then warn message will be produced at the end of __alloc_pages_slowpath(). Though this memory allocation can fallback to movable zone in check_after_alloc() if fallback is enabled, something should be done to prevent this pointless warn log. To solve this problem, fallback to movable zone if no suitable zone found. Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com> Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com> Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com> --- mm/page_alloc.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1e59761354e1..44d286286dbb 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4272,6 +4272,25 @@ check_retry_cpuset(int cpuset_mems_cookie, struct alloc_context *ac) } #ifdef CONFIG_MEMORY_RELIABLE +/* + * if fallback is enabled, fallback to movable zone if no dma/normal zone + * found + */ +static inline struct zone *mem_reliable_fallback_zone(gfp_t gfp_mask, + struct alloc_context *ac) +{ + if (!reliable_allow_fb_enabled()) + return NULL; + + if (!(gfp_mask & ___GFP_RELIABILITY)) + return NULL; + + ac->high_zoneidx = gfp_zone(gfp_mask & ~___GFP_RELIABILITY); + ac->preferred_zoneref = first_zones_zonelist( + ac->zonelist, ac->high_zoneidx, ac->nodemask); + return ac->preferred_zoneref->zone; +} + static inline void mem_reliable_fallback_slowpath(gfp_t gfp_mask, struct alloc_context *ac) { @@ -4290,6 +4309,11 @@ static inline void mem_reliable_fallback_slowpath(gfp_t gfp_mask, } } #else +static inline struct zone *mem_reliable_fallback_zone(gfp_t gfp_mask, + struct alloc_context *ac) +{ + return NULL; +} static inline void mem_reliable_fallback_slowpath(gfp_t gfp_mask, struct alloc_context *ac) {} #endif @@ -4339,8 +4363,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, */ ac->preferred_zoneref = first_zones_zonelist(ac->zonelist, ac->high_zoneidx, ac->nodemask); - if (!ac->preferred_zoneref->zone) - goto nopage; + if (!ac->preferred_zoneref->zone) { + if (!mem_reliable_fallback_zone(gfp_mask, ac)) + goto nopage; + } if (gfp_mask & __GFP_KSWAPD_RECLAIM) wake_all_kswapds(order, gfp_mask, ac); -- 2.25.1
1 3
0 0
[PATCH for openEuler 22.09] Memory model: Fix the memory model issues for Linux kernel
by Hanjun Guo 24 Sep '22

24 Sep '22
From: Jonas Oberhauser <jonas.oberhauser(a)huawei.com> This the update and fixes for memory model, simplify the model by removing redundancies, making semantics of seq-cst explicit, making ppo a subset of po, making ppo locally computable, as well as eliminating several spurious bugs in qspinlock and litmus tests, and ensuring correct compilation to the official power model. These issues were detected by Jonas Oberhauser, Viktor Vafeiadis, and the authors of "Verifying and Optimizing Compact NUMA-Aware Locks on Weak Memory Models", and the solutions are proposed by Jonas Oberhauser and Viktor Vafeiadis. Signed-off-by: Jonas Oberhauser <jonas.oberhauser(a)huawei.com> Signed-off-by: Hanjun Guo <guohanjun(a)huawei.com> --- tools/memory-model/linux-kernel.bell | 9 ++-- tools/memory-model/linux-kernel.cat | 100 +++++++++++++++++++---------------- 2 files changed, 60 insertions(+), 49 deletions(-) diff --git a/tools/memory-model/linux-kernel.bell b/tools/memory-model/linux-kernel.bell index 5be86b1..880b28b 100644 --- a/tools/memory-model/linux-kernel.bell +++ b/tools/memory-model/linux-kernel.bell @@ -4,6 +4,8 @@ * Copyright (C) 2016 Luc Maranget <luc.maranget(a)inria.fr> for Inria * Copyright (C) 2017 Alan Stern <stern(a)rowland.harvard.edu>, * Andrea Parri <parri.andrea(a)gmail.com> + * Copyright (C) 2022 Jonas Oberhauser <jonas.oberhauser(a)huawei.com> + * Viktor Vafeiadis <viktor(a)mpi-sws.org> * * An earlier version of this file appeared in the companion webpage for * "Frightening small children and disconcerting grown-ups: Concurrency @@ -16,10 +18,11 @@ enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) || 'release (*smp_store_release*) || 'acquire (*smp_load_acquire*) || + 'seq-cst (*smp_load, xchg...*) || 'noreturn (* R of non-return RMW *) -instructions R[{'once,'acquire,'noreturn}] -instructions W[{'once,'release}] -instructions RMW[{'once,'acquire,'release}] +instructions R[{'seq-cst, 'once,'acquire,'noreturn}] +instructions W[{'seq-cst, 'once,'release}] +instructions RMW[{'seq-cst, 'once,'acquire,'release}] enum Barriers = 'wmb (*smp_wmb*) || 'rmb (*smp_rmb*) || diff --git a/tools/memory-model/linux-kernel.cat b/tools/memory-model/linux-kernel.cat index d70315f..9f14d31 100644 --- a/tools/memory-model/linux-kernel.cat +++ b/tools/memory-model/linux-kernel.cat @@ -4,6 +4,8 @@ * Copyright (C) 2016 Luc Maranget <luc.maranget(a)inria.fr> for Inria * Copyright (C) 2017 Alan Stern <stern(a)rowland.harvard.edu>, * Andrea Parri <parri.andrea(a)gmail.com> + * Copyright (C) 2022 Jonas Oberhauser <jonas.oberhauser(a)huawei.com>, + * Viktor Vafeiadis <viktor(a)mpi-sws.org> * * An earlier version of this file appeared in the companion webpage for * "Frightening small children and disconcerting grown-ups: Concurrency @@ -25,25 +27,33 @@ include "lock.cat" (*******************) (* Release Acquire *) + let acq-po = [Acquire] ; po ; [M] let po-rel = [M] ; po ; [Release] let po-unlock-lock-po = po ; [UL] ; (po|rf) ; [LKR] ; po (* Fences *) -let R4rmb = R \ Noreturn (* Reads for which rmb works *) -let rmb = [R4rmb] ; fencerel(Rmb) ; [R4rmb] -let wmb = [W] ; fencerel(Wmb) ; [W] -let mb = ([M] ; fencerel(Mb) ; [M]) | - ([M] ; fencerel(Before-atomic) ; [RMW] ; po? ; [M]) | - ([M] ; po? ; [RMW] ; fencerel(After-atomic) ; [M]) | - ([M] ; po? ; [LKW] ; fencerel(After-spinlock) ; [M]) | - ([M] ; po ; [UL] ; (co | po) ; [LKW] ; - fencerel(After-unlock-lock) ; [M]) -let gp = po ; [Sync-rcu | Sync-srcu] ; po? -let strong-fence = mb | gp - +let R4rmb = R \ Noreturn +let rmb = [R4rmb] ; po ; [Rmb] ; po ; [R4rmb] +let wmb = [W] ; po ; [Wmb] ; po ; [W] + +let rmb-plain = [R \ Noreturn] ; po ; [Rmb] ; po \ ( po ; [W] ; po-loc) ; [R \ Noreturn] +let plain-wmb = [W] ; po \ (po-loc ; [W] ; po) ; [Wmb] ; po ; [W] +let strong-fence = + [M] ; po ; [Mb] ; po ; [M] + | [M] ; po ; [Before-atomic] ; po ; [RMW] ; po? ; [M] + | [M] ; po? ; [RMW] ; po ; [After-atomic] ; po ; [M] + | [M] ; po? ; [LKW] ; po ; [After-spinlock] ; po ; [M] + | [M] ; po ; [UL] ; po ; [LKR] ; po ; [After-unlock-lock] ; po ; [M] + | [M] ; po? ; [SC] ; po ; [M] + | [M] ; po ; [SC] ; po? ; [M] + | po ; [Sync-rcu | Sync-srcu] ; po? +let strong-sync = strong-fence + | ([M] ; po-unlock-lock-po ; [After-unlock-lock] ; po ; [M]) let nonrw-fence = strong-fence | po-rel | acq-po let fence = nonrw-fence | wmb | rmb + + let barrier = fencerel(Barrier | Rmb | Wmb | Mb | Sync-rcu | Sync-srcu | Before-atomic | After-atomic | Acquire | Release | Rcu-lock | Rcu-unlock | Srcu-lock | Srcu-unlock) | @@ -64,35 +74,33 @@ empty rmw & (fre ; coe) as atomic (* Instruction execution ordering *) (**********************************) + (* Preserved Program Order *) -let dep = addr | data -let rwdep = (dep | ctrl) ; [W] -let overwrite = co | fr -let to-w = rwdep | (overwrite & int) | (addr ; [Plain] ; wmb) -let to-r = addr | (dep ; [Marked] ; rfi) -let ppo = to-r | to-w | fence | (po-unlock-lock-po & int) +let dop = rmb-plain? ; (addr | data | ctrl | rfi)+; plain-wmb? +let to-w = (dop | po-loc) ; [W] +let lrs = ([W] ; po-loc ; [R]) \ (po-loc ; [W] ; po-loc) +let to-r = addr | ((addr | data) ; lrs) +let ppo = to-r | to-w | fence | (po ; [UL] ; po ; [LKR] ; po) (* Propagation: Ordering from release operations and strong fences. *) -let A-cumul(r) = (rfe ; [Marked])? ; r -let cumul-fence = [Marked] ; (A-cumul(strong-fence | po-rel) | wmb | - po-unlock-lock-po) ; [Marked] -let prop = [Marked] ; (overwrite & ext)? ; cumul-fence* ; - [Marked] ; rfe? ; [Marked] +let cumul-fence = [Marked] ; (rfe? ; (po-rel ; (rfe ; rmw)*) | wmb | po-unlock-lock-po) ; [Marked] +let prop = [Marked] ; ((co | fr) & ext) ; cumul-fence* ; [Marked] ; rfe? ; [Marked] + (* * Happens Before: Ordering from the passage of time. - * No fences needed here for prop because relation confined to one process. *) -let hb = [Marked] ; (ppo | rfe | ((prop \ id) & int)) ; [Marked] -acyclic hb as happens-before +let hb = [Marked] ; (ppo | rfe | prop ; strong-sync) ; [Marked] +acyclic hb + +(* No fences needed here for prop because relation confined to one process. *) +irreflexive (prop ; ppo*) + + + + -(****************************************) -(* Write and fence propagation ordering *) -(****************************************) -(* Propagation: Each non-rf link needs a strong fence. *) -let pb = prop ; strong-fence ; hb* ; [Marked] -acyclic pb as propagation (*******) (* RCU *) @@ -118,7 +126,7 @@ let srcu-rscsi = srcu-rscs^-1 * one but two non-rf relations, but only in conjunction with an RCU * read-side critical section. *) -let rcu-link = po? ; hb* ; pb* ; prop ; po +let rcu-link = po? ; hb* ; prop? ; po (* * Any sequence containing at least as many grace periods as RCU read-side @@ -139,20 +147,20 @@ let rec rcu-order = rcu-gp | srcu-gp | ((srcu-rscsi ; rcu-link ; rcu-order ; rcu-link ; srcu-gp) & loc) | (rcu-order ; rcu-link ; rcu-order) let rcu-fence = po ; rcu-order ; po? -let fence = fence | rcu-fence -let strong-fence = strong-fence | rcu-fence +let fence-rcu = fence | rcu-fence +let strong-sync-rcu = strong-sync | rcu-fence -(* rb orders instructions just as pb does *) -let rb = prop ; rcu-fence ; hb* ; pb* ; [Marked] +(* rb orders instructions just as hb does *) +let rb = prop? ; rcu-fence ; hb* ; [Marked] irreflexive rb as rcu (* - * The happens-before, propagation, and rcu constraints are all + * The happens-before and rcu constraints are all * expressions of temporal ordering. They could be replaced by * a single constraint on an "executes-before" relation, xb: * - * let xb = hb | pb | rb + * let xb = hb | rb * acyclic xb as executes-before *) @@ -166,24 +174,24 @@ let mixed-accesses = ([Plain & W] ; (po-loc \ barrier) ; [Marked]) | flag ~empty mixed-accesses as mixed-accesses (* Executes-before and visibility *) -let xbstar = (hb | pb | rb)* +let xbstar = (hb | rb)* let vis = cumul-fence* ; rfe? ; [Marked] ; - ((strong-fence ; [Marked] ; xbstar) | (xbstar & int)) + ((strong-sync-rcu ; [Marked] ; xbstar) | (xbstar & int)) (* Boundaries for lifetimes of plain accesses *) -let w-pre-bounded = [Marked] ; (addr | fence)? +let w-pre-bounded = [Marked] ; (addr | fence-rcu)? let r-pre-bounded = [Marked] ; (addr | nonrw-fence | ([R4rmb] ; fencerel(Rmb) ; [~Noreturn]))? -let w-post-bounded = fence? ; [Marked] +let w-post-bounded = fence-rcu? ; [Marked] let r-post-bounded = (nonrw-fence | ([~Noreturn] ; fencerel(Rmb) ; [R4rmb]))? ; [Marked] (* Visibility and executes-before for plain accesses *) -let ww-vis = fence | (strong-fence ; xbstar ; w-pre-bounded) | +let ww-vis = (strong-sync-rcu ; xbstar ; w-pre-bounded) | (w-post-bounded ; vis ; w-pre-bounded) -let wr-vis = fence | (strong-fence ; xbstar ; r-pre-bounded) | +let wr-vis = (strong-sync-rcu ; xbstar ; r-pre-bounded) | (w-post-bounded ; vis ; r-pre-bounded) -let rw-xbstar = fence | (r-post-bounded ; xbstar ; w-pre-bounded) +let rw-xbstar = (r-post-bounded ; xbstar ; w-pre-bounded) (* Potential races *) let pre-race = ext & ((Plain * M) | ((M \ IW) * Plain)) -- 1.7.12.4
1 0
0 0
[PATCH openEuler-22.09] mm: reliable: Fix ret errno to EACCES
by Zheng Zengkai 24 Sep '22

24 Sep '22
From: Ma Wupeng <mawupeng1(a)huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4SK3S CVE: NA -------------------------------- Commit bc25b3081709 ("mm: reliable: Use EINVAL in reliable_check") update EPERM to EINVAL try to pass LTP's proc01 test, however LTP only treat EACCESS as whitelist in the scenario. To solve this problem, update EINVAL to EACCESS. Fixes: bc25b3081709 ("mm: reliable: Use EINVAL in reliable_check") Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com> Reviewed-by: Chen Wandun <chenwandun(a)huawei.com> --- fs/proc/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 0c3a2eb61726..2d1af92653bb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1264,7 +1264,7 @@ static const struct file_operations proc_oom_score_adj_operations = { static inline int reliable_check(struct task_struct *task, struct pid *pid) { if (!mem_reliable_is_enabled()) - return -EINVAL; + return -EACCES; if (is_global_init(task)) return -EINVAL; -- 2.20.1
1 0
0 0
[PATCH openEuler-22.09] mm: reliable: Use EINVAL in reliable_check
by Zheng Zengkai 24 Sep '22

24 Sep '22
From: Ma Wupeng <mawupeng1(a)huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4SK3S CVE: NA -------------------------------- LTP's proc01 test was failing be because this ret code (1): proc01 1 TFAIL : proc01.c:400: read failed: /proc/self/task/1406366/reliable: errno=EPERM(1): Operation not permitted To slove this problem, replace EPERM with EINVAL in reliable_check(). Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com> Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com> Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com> --- fs/proc/base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 8ae7c2be70c2..0c3a2eb61726 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1264,14 +1264,14 @@ static const struct file_operations proc_oom_score_adj_operations = { static inline int reliable_check(struct task_struct *task, struct pid *pid) { if (!mem_reliable_is_enabled()) - return -EPERM; + return -EINVAL; if (is_global_init(task)) - return -EPERM; + return -EINVAL; if (!task->mm || (task->flags & PF_KTHREAD) || (task->flags & PF_EXITING)) - return -EPERM; + return -EINVAL; return 0; } -- 2.20.1
1 0
0 0
[PATCH openEuler-22.09] Revert "net: af_key: add check for pfkey_broadcast in function pfkey_process"
by Zheng Zengkai 22 Sep '22

22 Sep '22
From: Michal Kubecek <mkubecek(a)suse.cz> stable inclusion from stable-v5.10.122 commit 7fa8312879f78d255a63b372473a7016d4c29d67 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5L6D4 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 9c90c9b3e50e16d03c7f87d63e9db373974781e0 ] This reverts commit 4dc2a5a8f6754492180741facf2a8787f2c415d7. A non-zero return value from pfkey_broadcast() does not necessarily mean an error occurred as this function returns -ESRCH when no registered listener received the message. In particular, a call with BROADCAST_PROMISC_ONLY flag and null one_sk argument can never return zero so that this commit in fact prevents processing any PF_KEY message. One visible effect is that racoon daemon fails to find encryption algorithms like aes and refuses to start. Excluding -ESRCH return value would fix this but it's not obvious that we really want to bail out here and most other callers of pfkey_broadcast() also ignore the return value. Also, as pointed out by Steffen Klassert, PF_KEY is kind of deprecated and newer userspace code should use netlink instead so that we should only disturb the code for really important fixes. v2: add a comment explaining why is the return value ignored Signed-off-by: Michal Kubecek <mkubecek(a)suse.cz> Signed-off-by: Steffen Klassert <steffen.klassert(a)secunet.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com> Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com> --- net/key/af_key.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/key/af_key.c b/net/key/af_key.c index dca264844be4..aa3b1e0cd311 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2833,10 +2833,12 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadb void *ext_hdrs[SADB_EXT_MAX]; int err; - err = pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, - BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); - if (err) - return err; + /* Non-zero return value of pfkey_broadcast() does not always signal + * an error and even on an actual error we may still want to process + * the message so rather ignore the return value. + */ + pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, + BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); memset(ext_hdrs, 0, sizeof(ext_hdrs)); err = parse_exthdrs(skb, hdr, ext_hdrs); -- 2.20.1
1 0
0 0
[PATCH 1/2] net: hns3: fix error resume keep alive when remove hclgevf
by Laibin Qiu 22 Sep '22

22 Sep '22
From: Yonglong Liu <liuyonglong(a)huawei.com> driver inclusion category: https://gitee.com/openeuler/kernel/issues/I5S7WZ bugzilla: NA CVE: NA ---------------------------- When enable lots of vf, remove the driver of vf will call keep alive wrong resume. Fixes: 6a804d0a6068 ("net: hns3: fix keep alive can not resume problem when system busy") Signed-off-by: Yonglong Liu <liuyonglong(a)huawei.com> Reviewed-by: li yongxin <liyongxin1(a)huawei.com> Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com> --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 ++ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 1 + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 41a12df725b3..b4b1e440fba4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -7096,6 +7096,7 @@ int hclge_vport_start(struct hclge_vport *vport) struct hclge_dev *hdev = vport->back; vport->last_active_jiffies = jiffies; + set_bit(HCLGE_VPORT_STATE_START, &vport->state); set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); if (test_bit(vport->vport_id, hdev->vport_config_block)) { @@ -7113,6 +7114,7 @@ int hclge_vport_start(struct hclge_vport *vport) void hclge_vport_stop(struct hclge_vport *vport) { + clear_bit(HCLGE_VPORT_STATE_START, &vport->state); clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 8477dc343a40..99a55fa74cd4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -926,6 +926,7 @@ enum HCLGE_VPORT_STATE { HCLGE_VPORT_STATE_MAC_TBL_CHANGE, HCLGE_VPORT_STATE_PROMISC_CHANGE, HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE, + HCLGE_VPORT_STATE_START, HCLGE_VPORT_STATE_MAX }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 45f94cd33524..893f6e0ce473 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -644,7 +644,8 @@ static void hclge_vf_keep_alive(struct hclge_vport *vport) vport->last_active_jiffies = jiffies; - if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { + if (test_bit(HCLGE_VPORT_STATE_START, &vport->state) && + !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); dev_info(&hdev->pdev->dev, "VF %u keep alive resume!", -- 2.25.1
1 1
0 0
[PATCH 1/2] net: hns3: fix keep alive can not resume problem when system busy
by Laibin Qiu 22 Sep '22

22 Sep '22
From: Yonglong Liu <liuyonglong(a)huawei.com> driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5S7WZ CVE: NA ---------------------------- Currently, VF send keep alive to PF every 2s, and PF detect the keep alive for 8s, some case, the work queue may schedule late, cause keep alive lost, then the mac setting from PF may not affect to the VF, and the keep alive can not resume, only reset VF or reload VF driver can resume. This patch adds keep alive resume mechanism, and adds some debug print for this case. When link status change between keep alive lost and resume, the link status of VF may not the same as the PF, so adds push link status to VF to avoid this case. Signed-off-by: Yonglong Liu <liuyonglong(a)huawei.com> Reviewed-by: li yongxin <liyongxin1(a)huawei.com> Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com> --- .../hisilicon/hns3/hns3pf/hclge_main.c | 9 ++++++-- .../hisilicon/hns3/hns3pf/hclge_mbx.c | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 7e5e58470017..41a12df725b3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -4046,7 +4046,12 @@ static void hclge_update_vport_alive(struct hclge_dev *hdev) * receive a vf's alive msg for 8s, regards the vf is offline */ if (time_after(jiffies, vport->last_active_jiffies + 8 * HZ)) - clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); + if (test_and_clear_bit(HCLGE_VPORT_STATE_ALIVE, + &vport->state)) + dev_info(&hdev->pdev->dev, + "VF %u keep alive lost!", + vport->vport_id - + HCLGE_VF_VPORT_START_NUM); /* If vf is not alive, set to default value */ if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) @@ -7090,8 +7095,8 @@ int hclge_vport_start(struct hclge_vport *vport) { struct hclge_dev *hdev = vport->back; - set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); vport->last_active_jiffies = jiffies; + set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); if (test_bit(vport->vport_id, hdev->vport_config_block)) { if (vport->vport_id) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index b1b59c1f5cc6..45f94cd33524 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -639,7 +639,29 @@ static int hclge_reset_vf(struct hclge_vport *vport) static void hclge_vf_keep_alive(struct hclge_vport *vport) { + struct hclge_dev *hdev = vport->back; + int ret; + vport->last_active_jiffies = jiffies; + + if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { + set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state); + + dev_info(&hdev->pdev->dev, "VF %u keep alive resume!", + vport->vport_id - HCLGE_VF_VPORT_START_NUM); + + /* if vf support push link, need to push link status after keep + * alive restore, because the vf will not fetch the link status + * of it's own. + */ + ret = hclge_push_vf_link_status(vport); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to push link status to vf%u, ret=%d\n", + vport->vport_id - HCLGE_VF_VPORT_START_NUM, + ret); + } + } } static int hclge_set_vf_mtu(struct hclge_vport *vport, -- 2.25.1
1 1
0 0
  • ← Newer
  • 1
  • ...
  • 1566
  • 1567
  • 1568
  • 1569
  • 1570
  • 1571
  • 1572
  • ...
  • 1814
  • Older →

HyperKitty Powered by HyperKitty