diff options
author | Jens Axboe <axboe@kernel.dk> | 2013-04-02 04:04:39 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2013-04-02 04:04:39 -0400 |
commit | 64f8de4da7d3962632f152d3d702d68bb8accc29 (patch) | |
tree | c90a872a6d91c824635d59572e1e578980f4bc98 /lib/dma-debug.c | |
parent | f1fb3449efd5c49b48e35746bc7283eb9c73e3a0 (diff) | |
parent | b5c872ddb7083c7909fb76a170c3807e04564bb3 (diff) |
Merge branch 'writeback-workqueue' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq into for-3.10/core
Tejun writes:
-----
This is the pull request for the earlier patchset[1] with the same
name. It's only three patches (the first one was committed to
workqueue tree) but the merge strategy is a bit involved due to the
dependencies.
* Because the conversion needs features from wq/for-3.10,
block/for-3.10/core is based on rc3, and wq/for-3.10 has conflicts
with rc3, I pulled mainline (rc5) into wq/for-3.10 to prevent those
workqueue conflicts from flaring up in block tree.
* Resolving the issue that Jan and Dave raised about debugging
requires arch-wide changes. The patchset is being worked on[2] but
it'll have to go through -mm after these changes show up in -next,
and not included in this pull request.
The three commits are located in the following git branch.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git writeback-workqueue
Pulling it into block/for-3.10/core produces a conflict in
drivers/md/raid5.c between the following two commits.
e3620a3ad5 ("MD RAID5: Avoid accessing gendisk or queue structs when not available")
2f6db2a707 ("raid5: use bio_reset()")
The conflict is trivial - one removes an "if ()" conditional while the
other removes "rbi->bi_next = NULL" right above it. We just need to
remove both. The merged branch is available at
git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git block-test-merge
so that you can use it for verification. The test merge commit has
proper merge description.
While these changes are a bit of pain to route, they make code simpler
and even have, while minute, measureable performance gain[3] even on a
workload which isn't particularly favorable to showing the benefits of
this conversion.
----
Fixed up the conflict.
Conflicts:
drivers/md/raid5.c
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'lib/dma-debug.c')
-rw-r--r-- | lib/dma-debug.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 5e396accd3d0..d87a17a819d0 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -862,17 +862,21 @@ static void check_unmap(struct dma_debug_entry *ref) | |||
862 | entry = bucket_find_exact(bucket, ref); | 862 | entry = bucket_find_exact(bucket, ref); |
863 | 863 | ||
864 | if (!entry) { | 864 | if (!entry) { |
865 | /* must drop lock before calling dma_mapping_error */ | ||
866 | put_hash_bucket(bucket, &flags); | ||
867 | |||
865 | if (dma_mapping_error(ref->dev, ref->dev_addr)) { | 868 | if (dma_mapping_error(ref->dev, ref->dev_addr)) { |
866 | err_printk(ref->dev, NULL, | 869 | err_printk(ref->dev, NULL, |
867 | "DMA-API: device driver tries " | 870 | "DMA-API: device driver tries to free an " |
868 | "to free an invalid DMA memory address\n"); | 871 | "invalid DMA memory address\n"); |
869 | return; | 872 | } else { |
873 | err_printk(ref->dev, NULL, | ||
874 | "DMA-API: device driver tries to free DMA " | ||
875 | "memory it has not allocated [device " | ||
876 | "address=0x%016llx] [size=%llu bytes]\n", | ||
877 | ref->dev_addr, ref->size); | ||
870 | } | 878 | } |
871 | err_printk(ref->dev, NULL, "DMA-API: device driver tries " | 879 | return; |
872 | "to free DMA memory it has not allocated " | ||
873 | "[device address=0x%016llx] [size=%llu bytes]\n", | ||
874 | ref->dev_addr, ref->size); | ||
875 | goto out; | ||
876 | } | 880 | } |
877 | 881 | ||
878 | if (ref->size != entry->size) { | 882 | if (ref->size != entry->size) { |
@@ -936,7 +940,6 @@ static void check_unmap(struct dma_debug_entry *ref) | |||
936 | hash_bucket_del(entry); | 940 | hash_bucket_del(entry); |
937 | dma_entry_free(entry); | 941 | dma_entry_free(entry); |
938 | 942 | ||
939 | out: | ||
940 | put_hash_bucket(bucket, &flags); | 943 | put_hash_bucket(bucket, &flags); |
941 | } | 944 | } |
942 | 945 | ||
@@ -1082,13 +1085,27 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
1082 | ref.dev = dev; | 1085 | ref.dev = dev; |
1083 | ref.dev_addr = dma_addr; | 1086 | ref.dev_addr = dma_addr; |
1084 | bucket = get_hash_bucket(&ref, &flags); | 1087 | bucket = get_hash_bucket(&ref, &flags); |
1085 | entry = bucket_find_exact(bucket, &ref); | ||
1086 | 1088 | ||
1087 | if (!entry) | 1089 | list_for_each_entry(entry, &bucket->list, list) { |
1088 | goto out; | 1090 | if (!exact_match(&ref, entry)) |
1091 | continue; | ||
1092 | |||
1093 | /* | ||
1094 | * The same physical address can be mapped multiple | ||
1095 | * times. Without a hardware IOMMU this results in the | ||
1096 | * same device addresses being put into the dma-debug | ||
1097 | * hash multiple times too. This can result in false | ||
1098 | * positives being reported. Therefore we implement a | ||
1099 | * best-fit algorithm here which updates the first entry | ||
1100 | * from the hash which fits the reference value and is | ||
1101 | * not currently listed as being checked. | ||
1102 | */ | ||
1103 | if (entry->map_err_type == MAP_ERR_NOT_CHECKED) { | ||
1104 | entry->map_err_type = MAP_ERR_CHECKED; | ||
1105 | break; | ||
1106 | } | ||
1107 | } | ||
1089 | 1108 | ||
1090 | entry->map_err_type = MAP_ERR_CHECKED; | ||
1091 | out: | ||
1092 | put_hash_bucket(bucket, &flags); | 1109 | put_hash_bucket(bucket, &flags); |
1093 | } | 1110 | } |
1094 | EXPORT_SYMBOL(debug_dma_mapping_error); | 1111 | EXPORT_SYMBOL(debug_dma_mapping_error); |