Commit 88f3907f6f447899544beadf491dccb32015dacb

Authored by FUJITA Tomonori
Committed by Joerg Roedel
1 parent 884d05970b

dma-debug: fix debug_dma_sync_sg_for_cpu and debug_dma_sync_sg_for_device

DMA-mapping.txt says that debug_dma_sync_sg family must be called with
the _same_ one you passed into the dma_map_sg call, it should _NOT_ be
the 'count' value _returned_ from the dma_map_sg call.

debug_dma_sync_sg_for_cpu and debug_dma_sync_sg_for_device can't
handle this properly; they need to use the sg_mapped_ents in struct
dma_debug_entry as debug_dma_unmap_sg() does.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

Showing 1 changed file with 37 additions and 11 deletions Side-by-side Diff

... ... @@ -855,13 +855,32 @@
855 855 }
856 856 EXPORT_SYMBOL(debug_dma_map_sg);
857 857  
  858 +static int get_nr_mapped_entries(struct device *dev, struct scatterlist *s)
  859 +{
  860 + struct dma_debug_entry *entry;
  861 + struct hash_bucket *bucket;
  862 + unsigned long flags;
  863 + int mapped_ents = 0;
  864 + struct dma_debug_entry ref;
  865 +
  866 + ref.dev = dev;
  867 + ref.dev_addr = sg_dma_address(s);
  868 + ref.size = sg_dma_len(s),
  869 +
  870 + bucket = get_hash_bucket(&ref, &flags);
  871 + entry = hash_bucket_find(bucket, &ref);
  872 + if (entry)
  873 + mapped_ents = entry->sg_mapped_ents;
  874 + put_hash_bucket(bucket, &flags);
  875 +
  876 + return mapped_ents;
  877 +}
  878 +
858 879 void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
859 880 int nelems, int dir)
860 881 {
861   - struct dma_debug_entry *entry;
862 882 struct scatterlist *s;
863 883 int mapped_ents = 0, i;
864   - unsigned long flags;
865 884  
866 885 if (unlikely(global_disable))
867 886 return;
868 887  
... ... @@ -881,14 +900,9 @@
881 900 if (mapped_ents && i >= mapped_ents)
882 901 break;
883 902  
884   - if (mapped_ents == 0) {
885   - struct hash_bucket *bucket;
  903 + if (!i) {
886 904 ref.sg_call_ents = nelems;
887   - bucket = get_hash_bucket(&ref, &flags);
888   - entry = hash_bucket_find(bucket, &ref);
889   - if (entry)
890   - mapped_ents = entry->sg_mapped_ents;
891   - put_hash_bucket(bucket, &flags);
  905 + mapped_ents = get_nr_mapped_entries(dev, s);
892 906 }
893 907  
894 908 check_unmap(&ref);
895 909  
... ... @@ -990,12 +1004,18 @@
990 1004 int nelems, int direction)
991 1005 {
992 1006 struct scatterlist *s;
993   - int i;
  1007 + int mapped_ents = 0, i;
994 1008  
995 1009 if (unlikely(global_disable))
996 1010 return;
997 1011  
998 1012 for_each_sg(sg, s, nelems, i) {
  1013 + if (!i)
  1014 + mapped_ents = get_nr_mapped_entries(dev, s);
  1015 +
  1016 + if (i >= mapped_ents)
  1017 + break;
  1018 +
999 1019 check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
1000 1020 direction, true);
1001 1021 }
1002 1022  
... ... @@ -1006,12 +1026,18 @@
1006 1026 int nelems, int direction)
1007 1027 {
1008 1028 struct scatterlist *s;
1009   - int i;
  1029 + int mapped_ents = 0, i;
1010 1030  
1011 1031 if (unlikely(global_disable))
1012 1032 return;
1013 1033  
1014 1034 for_each_sg(sg, s, nelems, i) {
  1035 + if (!i)
  1036 + mapped_ents = get_nr_mapped_entries(dev, s);
  1037 +
  1038 + if (i >= mapped_ents)
  1039 + break;
  1040 +
1015 1041 check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
1016 1042 direction, false);
1017 1043 }