@@ -45,10 +45,10 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
45
45
size_t ret = 0 ;
46
46
47
47
dmabuf = dentry -> d_fsdata ;
48
- mutex_lock ( & dmabuf -> lock );
48
+ dma_resv_lock ( dmabuf -> resv , NULL );
49
49
if (dmabuf -> name )
50
50
ret = strlcpy (name , dmabuf -> name , DMA_BUF_NAME_LEN );
51
- mutex_unlock ( & dmabuf -> lock );
51
+ dma_resv_unlock ( dmabuf -> resv );
52
52
53
53
return dynamic_dname (dentry , buffer , buflen , "/%s:%s" ,
54
54
dentry -> d_name .name , ret > 0 ? name : "" );
@@ -334,7 +334,7 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
334
334
if (IS_ERR (name ))
335
335
return PTR_ERR (name );
336
336
337
- mutex_lock ( & dmabuf -> lock );
337
+ dma_resv_lock ( dmabuf -> resv , NULL );
338
338
if (!list_empty (& dmabuf -> attachments )) {
339
339
ret = - EBUSY ;
340
340
kfree (name );
@@ -344,7 +344,7 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
344
344
dmabuf -> name = name ;
345
345
346
346
out_unlock :
347
- mutex_unlock ( & dmabuf -> lock );
347
+ dma_resv_unlock ( dmabuf -> resv );
348
348
return ret ;
349
349
}
350
350
@@ -403,10 +403,10 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file)
403
403
/* Don't count the temporary reference taken inside procfs seq_show */
404
404
seq_printf (m , "count:\t%ld\n" , file_count (dmabuf -> file ) - 1 );
405
405
seq_printf (m , "exp_name:\t%s\n" , dmabuf -> exp_name );
406
- mutex_lock ( & dmabuf -> lock );
406
+ dma_resv_lock ( dmabuf -> resv , NULL );
407
407
if (dmabuf -> name )
408
408
seq_printf (m , "name:\t%s\n" , dmabuf -> name );
409
- mutex_unlock ( & dmabuf -> lock );
409
+ dma_resv_unlock ( dmabuf -> resv );
410
410
}
411
411
412
412
static const struct file_operations dma_buf_fops = {
@@ -525,6 +525,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
525
525
return ERR_PTR (- EINVAL );
526
526
}
527
527
528
+ if (WARN_ON (exp_info -> ops -> cache_sgt_mapping &&
529
+ exp_info -> ops -> dynamic_mapping ))
530
+ return ERR_PTR (- EINVAL );
531
+
528
532
if (!try_module_get (exp_info -> owner ))
529
533
return ERR_PTR (- ENOENT );
530
534
@@ -645,10 +649,11 @@ void dma_buf_put(struct dma_buf *dmabuf)
645
649
EXPORT_SYMBOL_GPL (dma_buf_put );
646
650
647
651
/**
648
- * dma_buf_attach - Add the device to dma_buf's attachments list; optionally,
652
+ * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list; optionally,
649
653
* calls attach() of dma_buf_ops to allow device-specific attach functionality
650
- * @dmabuf: [in] buffer to attach device to.
651
- * @dev: [in] device to be attached.
654
+ * @dmabuf: [in] buffer to attach device to.
655
+ * @dev: [in] device to be attached.
656
+ * @dynamic_mapping: [in] calling convention for map/unmap
652
657
*
653
658
* Returns struct dma_buf_attachment pointer for this attachment. Attachments
654
659
* must be cleaned up by calling dma_buf_detach().
@@ -662,8 +667,9 @@ EXPORT_SYMBOL_GPL(dma_buf_put);
662
667
* accessible to @dev, and cannot be moved to a more suitable place. This is
663
668
* indicated with the error code -EBUSY.
664
669
*/
665
- struct dma_buf_attachment * dma_buf_attach (struct dma_buf * dmabuf ,
666
- struct device * dev )
670
+ struct dma_buf_attachment *
671
+ dma_buf_dynamic_attach (struct dma_buf * dmabuf , struct device * dev ,
672
+ bool dynamic_mapping )
667
673
{
668
674
struct dma_buf_attachment * attach ;
669
675
int ret ;
@@ -677,25 +683,69 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
677
683
678
684
attach -> dev = dev ;
679
685
attach -> dmabuf = dmabuf ;
680
-
681
- mutex_lock (& dmabuf -> lock );
686
+ attach -> dynamic_mapping = dynamic_mapping ;
682
687
683
688
if (dmabuf -> ops -> attach ) {
684
689
ret = dmabuf -> ops -> attach (dmabuf , attach );
685
690
if (ret )
686
691
goto err_attach ;
687
692
}
693
+ dma_resv_lock (dmabuf -> resv , NULL );
688
694
list_add (& attach -> node , & dmabuf -> attachments );
695
+ dma_resv_unlock (dmabuf -> resv );
689
696
690
- mutex_unlock (& dmabuf -> lock );
697
+ /* When either the importer or the exporter can't handle dynamic
698
+ * mappings we cache the mapping here to avoid issues with the
699
+ * reservation object lock.
700
+ */
701
+ if (dma_buf_attachment_is_dynamic (attach ) !=
702
+ dma_buf_is_dynamic (dmabuf )) {
703
+ struct sg_table * sgt ;
704
+
705
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
706
+ dma_resv_lock (attach -> dmabuf -> resv , NULL );
707
+
708
+ sgt = dmabuf -> ops -> map_dma_buf (attach , DMA_BIDIRECTIONAL );
709
+ if (!sgt )
710
+ sgt = ERR_PTR (- ENOMEM );
711
+ if (IS_ERR (sgt )) {
712
+ ret = PTR_ERR (sgt );
713
+ goto err_unlock ;
714
+ }
715
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
716
+ dma_resv_unlock (attach -> dmabuf -> resv );
717
+ attach -> sgt = sgt ;
718
+ attach -> dir = DMA_BIDIRECTIONAL ;
719
+ }
691
720
692
721
return attach ;
693
722
694
723
err_attach :
695
724
kfree (attach );
696
- mutex_unlock (& dmabuf -> lock );
725
+ return ERR_PTR (ret );
726
+
727
+ err_unlock :
728
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
729
+ dma_resv_unlock (attach -> dmabuf -> resv );
730
+
731
+ dma_buf_detach (dmabuf , attach );
697
732
return ERR_PTR (ret );
698
733
}
734
+ EXPORT_SYMBOL_GPL (dma_buf_dynamic_attach );
735
+
736
+ /**
737
+ * dma_buf_attach - Wrapper for dma_buf_dynamic_attach
738
+ * @dmabuf: [in] buffer to attach device to.
739
+ * @dev: [in] device to be attached.
740
+ *
741
+ * Wrapper to call dma_buf_dynamic_attach() for drivers which still use a static
742
+ * mapping.
743
+ */
744
+ struct dma_buf_attachment * dma_buf_attach (struct dma_buf * dmabuf ,
745
+ struct device * dev )
746
+ {
747
+ return dma_buf_dynamic_attach (dmabuf , dev , false);
748
+ }
699
749
EXPORT_SYMBOL_GPL (dma_buf_attach );
700
750
701
751
/**
@@ -711,15 +761,22 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
711
761
if (WARN_ON (!dmabuf || !attach ))
712
762
return ;
713
763
714
- if (attach -> sgt )
764
+ if (attach -> sgt ) {
765
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
766
+ dma_resv_lock (attach -> dmabuf -> resv , NULL );
767
+
715
768
dmabuf -> ops -> unmap_dma_buf (attach , attach -> sgt , attach -> dir );
716
769
717
- mutex_lock (& dmabuf -> lock );
770
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
771
+ dma_resv_unlock (attach -> dmabuf -> resv );
772
+ }
773
+
774
+ dma_resv_lock (dmabuf -> resv , NULL );
718
775
list_del (& attach -> node );
776
+ dma_resv_unlock (dmabuf -> resv );
719
777
if (dmabuf -> ops -> detach )
720
778
dmabuf -> ops -> detach (dmabuf , attach );
721
779
722
- mutex_unlock (& dmabuf -> lock );
723
780
kfree (attach );
724
781
}
725
782
EXPORT_SYMBOL_GPL (dma_buf_detach );
@@ -749,6 +806,9 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
749
806
if (WARN_ON (!attach || !attach -> dmabuf ))
750
807
return ERR_PTR (- EINVAL );
751
808
809
+ if (dma_buf_attachment_is_dynamic (attach ))
810
+ dma_resv_assert_held (attach -> dmabuf -> resv );
811
+
752
812
if (attach -> sgt ) {
753
813
/*
754
814
* Two mappings with different directions for the same
@@ -761,6 +821,9 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
761
821
return attach -> sgt ;
762
822
}
763
823
824
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
825
+ dma_resv_assert_held (attach -> dmabuf -> resv );
826
+
764
827
sg_table = attach -> dmabuf -> ops -> map_dma_buf (attach , direction );
765
828
if (!sg_table )
766
829
sg_table = ERR_PTR (- ENOMEM );
@@ -793,9 +856,15 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
793
856
if (WARN_ON (!attach || !attach -> dmabuf || !sg_table ))
794
857
return ;
795
858
859
+ if (dma_buf_attachment_is_dynamic (attach ))
860
+ dma_resv_assert_held (attach -> dmabuf -> resv );
861
+
796
862
if (attach -> sgt == sg_table )
797
863
return ;
798
864
865
+ if (dma_buf_is_dynamic (attach -> dmabuf ))
866
+ dma_resv_assert_held (attach -> dmabuf -> resv );
867
+
799
868
attach -> dmabuf -> ops -> unmap_dma_buf (attach , sg_table , direction );
800
869
}
801
870
EXPORT_SYMBOL_GPL (dma_buf_unmap_attachment );
@@ -1171,13 +1240,10 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
1171
1240
"size" , "flags" , "mode" , "count" , "ino" );
1172
1241
1173
1242
list_for_each_entry (buf_obj , & db_list .head , list_node ) {
1174
- ret = mutex_lock_interruptible (& buf_obj -> lock );
1175
1243
1176
- if (ret ) {
1177
- seq_puts (s ,
1178
- "\tERROR locking buffer object: skipping\n" );
1179
- continue ;
1180
- }
1244
+ ret = dma_resv_lock_interruptible (buf_obj -> resv , NULL );
1245
+ if (ret )
1246
+ goto error_unlock ;
1181
1247
1182
1248
seq_printf (s , "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n" ,
1183
1249
buf_obj -> size ,
@@ -1223,19 +1289,23 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
1223
1289
seq_printf (s , "\t%s\n" , dev_name (attach_obj -> dev ));
1224
1290
attach_count ++ ;
1225
1291
}
1292
+ dma_resv_unlock (buf_obj -> resv );
1226
1293
1227
1294
seq_printf (s , "Total %d devices attached\n\n" ,
1228
1295
attach_count );
1229
1296
1230
1297
count ++ ;
1231
1298
size += buf_obj -> size ;
1232
- mutex_unlock (& buf_obj -> lock );
1233
1299
}
1234
1300
1235
1301
seq_printf (s , "\nTotal %d objects, %zu bytes\n" , count , size );
1236
1302
1237
1303
mutex_unlock (& db_list .lock );
1238
1304
return 0 ;
1305
+
1306
+ error_unlock :
1307
+ mutex_unlock (& db_list .lock );
1308
+ return ret ;
1239
1309
}
1240
1310
1241
1311
DEFINE_SHOW_ATTRIBUTE (dma_buf_debug );
0 commit comments