| 
					
				 | 
			
			
				@@ -1608,3 +1608,59 @@ cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 bool add_front) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct rb_node **p, *parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cfq_queue *__cfqq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long rb_key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cfq_rb_root *service_tree; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int left; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int new_cfqq = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						cfqq_type(cfqq)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (cfq_class_idle(cfqq)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		rb_key = CFQ_IDLE_DELAY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		parent = rb_last(&service_tree->rb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (parent && parent != &cfqq->rb_node) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			__cfqq = rb_entry(parent, struct cfq_queue, rb_node); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			rb_key += __cfqq->rb_key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			rb_key += jiffies; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (!add_front) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Get our rb key offset. Subtract any residual slice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * value carried from last service. A negative resid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * count indicates slice overrun, and this should position 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * the next service time further away in the tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		rb_key -= cfqq->slice_resid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		cfqq->slice_resid = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		rb_key = -HZ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		__cfqq = cfq_rb_first(service_tree); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		rb_key += __cfqq ? __cfqq->rb_key : jiffies; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!RB_EMPTY_NODE(&cfqq->rb_node)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		new_cfqq = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * same position, nothing more to do 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (rb_key == cfqq->rb_key && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		    cfqq->service_tree == service_tree) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		cfq_rb_erase(&cfqq->rb_node, cfqq->service_tree); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		cfqq->service_tree = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	left = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	parent = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cfqq->service_tree = service_tree; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	p = &service_tree->rb.rb_node; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	while (*p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct rb_node **n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		parent = *p; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		__cfqq = rb_entry(parent, struct cfq_queue, rb_node); 
			 |