Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

intel-iommu: Remove superfluous iova_alloc_lock from IOVA code

We only ever obtain this lock immediately before the iova_rbtree_lock,
and release it immediately after the iova_rbtree_lock. So ditch it and
just use iova_rbtree_lock.

[v2: Remove the lockdep bits this time too]
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

+4 -16
-3
drivers/pci/intel-iommu.c
··· 1309 1309 } 1310 1310 1311 1311 static struct iova_domain reserved_iova_list; 1312 - static struct lock_class_key reserved_alloc_key; 1313 1312 static struct lock_class_key reserved_rbtree_key; 1314 1313 1315 1314 static void dmar_init_reserved_ranges(void) ··· 1319 1320 1320 1321 init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); 1321 1322 1322 - lockdep_set_class(&reserved_iova_list.iova_alloc_lock, 1323 - &reserved_alloc_key); 1324 1323 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock, 1325 1324 &reserved_rbtree_key); 1326 1325
+4 -12
drivers/pci/iova.c
··· 22 22 void 23 23 init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit) 24 24 { 25 - spin_lock_init(&iovad->iova_alloc_lock); 26 25 spin_lock_init(&iovad->iova_rbtree_lock); 27 26 iovad->rbroot = RB_ROOT; 28 27 iovad->cached32_node = NULL; ··· 204 205 unsigned long limit_pfn, 205 206 bool size_aligned) 206 207 { 207 - unsigned long flags; 208 208 struct iova *new_iova; 209 209 int ret; 210 210 ··· 217 219 if (size_aligned) 218 220 size = __roundup_pow_of_two(size); 219 221 220 - spin_lock_irqsave(&iovad->iova_alloc_lock, flags); 221 222 ret = __alloc_and_insert_iova_range(iovad, size, limit_pfn, 222 223 new_iova, size_aligned); 223 224 224 - spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags); 225 225 if (ret) { 226 226 free_iova_mem(new_iova); 227 227 return NULL; ··· 377 381 struct iova *iova; 378 382 unsigned int overlap = 0; 379 383 380 - spin_lock_irqsave(&iovad->iova_alloc_lock, flags); 381 - spin_lock(&iovad->iova_rbtree_lock); 384 + spin_lock_irqsave(&iovad->iova_rbtree_lock, flags); 382 385 for (node = rb_first(&iovad->rbroot); node; node = rb_next(node)) { 383 386 if (__is_range_overlap(node, pfn_lo, pfn_hi)) { 384 387 iova = container_of(node, struct iova, node); ··· 397 402 iova = __insert_new_range(iovad, pfn_lo, pfn_hi); 398 403 finish: 399 404 400 - spin_unlock(&iovad->iova_rbtree_lock); 401 - spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags); 405 + spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); 402 406 return iova; 403 407 } 404 408 ··· 414 420 unsigned long flags; 415 421 struct rb_node *node; 416 422 417 - spin_lock_irqsave(&from->iova_alloc_lock, flags); 418 - spin_lock(&from->iova_rbtree_lock); 423 + spin_lock_irqsave(&from->iova_rbtree_lock, flags); 419 424 for (node = rb_first(&from->rbroot); node; node = rb_next(node)) { 420 425 struct iova *iova = container_of(node, struct iova, node); 421 426 struct iova *new_iova; ··· 423 430 printk(KERN_ERR "Reserve iova range %lx@%lx failed\n", 424 431 iova->pfn_lo, iova->pfn_lo); 425 432 } 426 - spin_unlock(&from->iova_rbtree_lock); 427 - spin_unlock_irqrestore(&from->iova_alloc_lock, flags); 433 + spin_unlock_irqrestore(&from->iova_rbtree_lock, flags); 428 434 }
-1
include/linux/iova.h
··· 28 28 29 29 /* holds all the iova translations for a domain */ 30 30 struct iova_domain { 31 - spinlock_t iova_alloc_lock;/* Lock to protect iova allocation */ 32 31 spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ 33 32 struct rb_root rbroot; /* iova domain rbtree root */ 34 33 struct rb_node *cached32_node; /* Save last alloced node */