mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: sched: tbf: don't call qdisc_put() while holding tree lock
The issue is the same to commitc2999f7fb0("net: sched: multiq: don't call qdisc_put() while holding tree lock"). Qdiscs call qdisc_put() while holding sch tree spinlock, which results sleeping-while-atomic BUG. Fixes:c266f64dbf("net: sched: protect block state with mutex") Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> Link: https://lore.kernel.org/r/20220826013930.340121-1-shaozhengchao@huawei.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
		
							parent
							
								
									cb10b0f91c
								
							
						
					
					
						commit
						b05972f01e
					
				
					 1 changed files with 3 additions and 1 deletions
				
			
		| 
						 | 
					@ -356,6 +356,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 | 
				
			||||||
	struct nlattr *tb[TCA_TBF_MAX + 1];
 | 
						struct nlattr *tb[TCA_TBF_MAX + 1];
 | 
				
			||||||
	struct tc_tbf_qopt *qopt;
 | 
						struct tc_tbf_qopt *qopt;
 | 
				
			||||||
	struct Qdisc *child = NULL;
 | 
						struct Qdisc *child = NULL;
 | 
				
			||||||
 | 
						struct Qdisc *old = NULL;
 | 
				
			||||||
	struct psched_ratecfg rate;
 | 
						struct psched_ratecfg rate;
 | 
				
			||||||
	struct psched_ratecfg peak;
 | 
						struct psched_ratecfg peak;
 | 
				
			||||||
	u64 max_size;
 | 
						u64 max_size;
 | 
				
			||||||
| 
						 | 
					@ -447,7 +448,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 | 
				
			||||||
	sch_tree_lock(sch);
 | 
						sch_tree_lock(sch);
 | 
				
			||||||
	if (child) {
 | 
						if (child) {
 | 
				
			||||||
		qdisc_tree_flush_backlog(q->qdisc);
 | 
							qdisc_tree_flush_backlog(q->qdisc);
 | 
				
			||||||
		qdisc_put(q->qdisc);
 | 
							old = q->qdisc;
 | 
				
			||||||
		q->qdisc = child;
 | 
							q->qdisc = child;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	q->limit = qopt->limit;
 | 
						q->limit = qopt->limit;
 | 
				
			||||||
| 
						 | 
					@ -467,6 +468,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 | 
				
			||||||
	memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
 | 
						memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sch_tree_unlock(sch);
 | 
						sch_tree_unlock(sch);
 | 
				
			||||||
 | 
						qdisc_put(old);
 | 
				
			||||||
	err = 0;
 | 
						err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tbf_offload_change(sch);
 | 
						tbf_offload_change(sch);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue