diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-03-03 17:58:11 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:29 -0400 |
commit | fe9a643157747cf85ecc07cd341e448c5849364f (patch) | |
tree | 15b7c012fc04d8bae1965ae429dbed872bb9d48e | |
parent | 27ce51df9a333ca7e05e09f6d25becf26ac1ff45 (diff) |
isci: pad stp and smp request sizes
Ross says:
"The memory allocation for these requests doesn’t take into account the
additional memory needed when the code in
scic_sds_s[mst]p_request_assign_buffers() shifts the struct
scu_task_context so that it is cache line aligned:
In an example from my machine, total buffer that I’ve given to SCIC goes
from 0x410024566f84 to 0x410024567308. From this same example, this
call shifts my task_context_buffer from 0x410024567208 to
0x410024567240.
This means that the task_context_buffer that used to range from
0x410024567208 to 0x410024567308 instead now goes from 0x410024567240 to
0x410024567340.
When the memset() call at the end of scic_task_request_construct()
clears out this task_context_buffer, it does so from 0x410024567240 to
0x410024567340, effectively killing whatever buffer follows this
allocation in memory."
djbw:
Use the kernel's PTR_ALIGN instead of
scic_sds_request_align_task_context_buffer() and SMP_CACHE_BYTES instead of
the local CACHE_LINE_SIZE definition.
TODO: These allocations really want to be better defined in a union rather
than opaque buffers carved up by macros.
Reported-by: Ross Zwisler <ross.zwisler@intel.com>
Signed-off-by: Jacek Danecki <Jacek.Danecki@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_request.c | 10 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_request.h | 22 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_smp_request.c | 5 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_stp_request.c | 38 |
4 files changed, 24 insertions, 51 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c index 7b9ce1e878a7..00bebb9c0692 100644 --- a/drivers/scsi/isci/core/scic_sds_request.c +++ b/drivers/scsi/isci/core/scic_sds_request.c | |||
@@ -222,7 +222,7 @@ static u32 scic_sds_ssp_request_get_object_size(void) | |||
222 | return sizeof(struct scic_sds_request) | 222 | return sizeof(struct scic_sds_request) |
223 | + scic_ssp_io_request_get_object_size() | 223 | + scic_ssp_io_request_get_object_size() |
224 | + sizeof(struct scu_task_context) | 224 | + sizeof(struct scu_task_context) |
225 | + CACHE_LINE_SIZE | 225 | + SMP_CACHE_BYTES |
226 | + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS; | 226 | + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS; |
227 | } | 227 | } |
228 | 228 | ||
@@ -395,13 +395,15 @@ static void scic_sds_ssp_io_request_assign_buffers( | |||
395 | this_request->sgl_element_pair_buffer = | 395 | this_request->sgl_element_pair_buffer = |
396 | scic_sds_ssp_request_get_sgl_element_buffer(this_request); | 396 | scic_sds_ssp_request_get_sgl_element_buffer(this_request); |
397 | this_request->sgl_element_pair_buffer = | 397 | this_request->sgl_element_pair_buffer = |
398 | scic_sds_request_align_sgl_element_buffer(this_request->sgl_element_pair_buffer); | 398 | PTR_ALIGN(this_request->sgl_element_pair_buffer, |
399 | sizeof(struct scu_sgl_element_pair)); | ||
399 | 400 | ||
400 | if (this_request->was_tag_assigned_by_user == false) { | 401 | if (this_request->was_tag_assigned_by_user == false) { |
401 | this_request->task_context_buffer = | 402 | this_request->task_context_buffer = |
402 | scic_sds_ssp_request_get_task_context_buffer(this_request); | 403 | scic_sds_ssp_request_get_task_context_buffer(this_request); |
403 | this_request->task_context_buffer = | 404 | this_request->task_context_buffer = |
404 | scic_sds_request_align_task_context_buffer(this_request->task_context_buffer); | 405 | PTR_ALIGN(this_request->task_context_buffer, |
406 | SMP_CACHE_BYTES); | ||
405 | } | 407 | } |
406 | } | 408 | } |
407 | 409 | ||
@@ -638,7 +640,7 @@ static void scic_sds_ssp_task_request_assign_buffers( | |||
638 | this_request->task_context_buffer = | 640 | this_request->task_context_buffer = |
639 | scic_sds_ssp_task_request_get_task_context_buffer(this_request); | 641 | scic_sds_ssp_task_request_get_task_context_buffer(this_request); |
640 | this_request->task_context_buffer = | 642 | this_request->task_context_buffer = |
641 | scic_sds_request_align_task_context_buffer(this_request->task_context_buffer); | 643 | PTR_ALIGN(this_request->task_context_buffer, SMP_CACHE_BYTES); |
642 | } | 644 | } |
643 | } | 645 | } |
644 | 646 | ||
diff --git a/drivers/scsi/isci/core/scic_sds_request.h b/drivers/scsi/isci/core/scic_sds_request.h index 19b6feef373e..06b53c3b0aa0 100644 --- a/drivers/scsi/isci/core/scic_sds_request.h +++ b/drivers/scsi/isci/core/scic_sds_request.h | |||
@@ -313,28 +313,6 @@ extern const struct scic_sds_io_request_state_handler scic_sds_smp_request_start | |||
313 | #define scic_sds_request_get_task_context(request) \ | 313 | #define scic_sds_request_get_task_context(request) \ |
314 | ((request)->task_context_buffer) | 314 | ((request)->task_context_buffer) |
315 | 315 | ||
316 | #define CACHE_LINE_SIZE (64) | ||
317 | #define scic_sds_request_align_task_context_buffer(address) \ | ||
318 | ((struct scu_task_context *)(\ | ||
319 | (((unsigned long)(address)) + (CACHE_LINE_SIZE - 1)) \ | ||
320 | & ~(CACHE_LINE_SIZE - 1) \ | ||
321 | )) | ||
322 | |||
323 | /** | ||
324 | * scic_sds_request_align_sgl_element_buffer() - | ||
325 | * | ||
326 | * This macro will align the memory address so that it is correct for the SCU | ||
327 | * hardware to DMA the SGL element pairs. | ||
328 | */ | ||
329 | #define scic_sds_request_align_sgl_element_buffer(address) \ | ||
330 | ((struct scu_sgl_element_pair *)(\ | ||
331 | ((char *)(address)) \ | ||
332 | + (\ | ||
333 | ((~(unsigned long)(address)) + 1) \ | ||
334 | & (sizeof(struct scu_sgl_element_pair) - 1) \ | ||
335 | ) \ | ||
336 | )) | ||
337 | |||
338 | /** | 316 | /** |
339 | * scic_sds_request_set_status() - | 317 | * scic_sds_request_set_status() - |
340 | * | 318 | * |
diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c index 85c890630d60..962bd3994f10 100644 --- a/drivers/scsi/isci/core/scic_sds_smp_request.c +++ b/drivers/scsi/isci/core/scic_sds_smp_request.c | |||
@@ -80,7 +80,8 @@ u32 scic_sds_smp_request_get_object_size(void) | |||
80 | return sizeof(struct scic_sds_request) | 80 | return sizeof(struct scic_sds_request) |
81 | + sizeof(struct smp_request) | 81 | + sizeof(struct smp_request) |
82 | + sizeof(struct smp_response) | 82 | + sizeof(struct smp_response) |
83 | + sizeof(struct scu_task_context); | 83 | + sizeof(struct scu_task_context) |
84 | + SMP_CACHE_BYTES; | ||
84 | } | 85 | } |
85 | 86 | ||
86 | /** | 87 | /** |
@@ -137,7 +138,7 @@ void scic_sds_smp_request_assign_buffers( | |||
137 | this_request->task_context_buffer = | 138 | this_request->task_context_buffer = |
138 | scic_sds_smp_request_get_task_context_buffer(this_request); | 139 | scic_sds_smp_request_get_task_context_buffer(this_request); |
139 | this_request->task_context_buffer = | 140 | this_request->task_context_buffer = |
140 | scic_sds_request_align_task_context_buffer(this_request->task_context_buffer); | 141 | PTR_ALIGN(this_request->task_context_buffer, SMP_CACHE_BYTES); |
141 | } | 142 | } |
142 | 143 | ||
143 | } | 144 | } |
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.c b/drivers/scsi/isci/core/scic_sds_stp_request.c index 0f17a28dd196..8da309f81ac2 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.c +++ b/drivers/scsi/isci/core/scic_sds_stp_request.c | |||
@@ -131,33 +131,25 @@ u32 scic_sds_stp_request_get_object_size(void) | |||
131 | + sizeof(struct sata_fis_reg_h2d) | 131 | + sizeof(struct sata_fis_reg_h2d) |
132 | + sizeof(struct sata_fis_reg_d2h) | 132 | + sizeof(struct sata_fis_reg_d2h) |
133 | + sizeof(struct scu_task_context) | 133 | + sizeof(struct scu_task_context) |
134 | + SMP_CACHE_BYTES | ||
134 | + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS; | 135 | + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS; |
135 | } | 136 | } |
136 | 137 | ||
137 | /** | 138 | void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req) |
138 | * | ||
139 | * | ||
140 | * | ||
141 | */ | ||
142 | void scic_sds_stp_request_assign_buffers( | ||
143 | struct scic_sds_request *request) | ||
144 | { | 139 | { |
145 | struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request; | 140 | struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent); |
146 | 141 | ||
147 | this_request->parent.command_buffer = | 142 | sci_req->command_buffer = scic_sds_stp_request_get_h2d_reg_buffer(stp_req); |
148 | scic_sds_stp_request_get_h2d_reg_buffer(this_request); | 143 | sci_req->response_buffer = scic_sds_stp_request_get_response_buffer(stp_req); |
149 | this_request->parent.response_buffer = | 144 | sci_req->sgl_element_pair_buffer = scic_sds_stp_request_get_sgl_element_buffer(stp_req); |
150 | scic_sds_stp_request_get_response_buffer(this_request); | 145 | sci_req->sgl_element_pair_buffer = PTR_ALIGN(sci_req->sgl_element_pair_buffer, |
151 | this_request->parent.sgl_element_pair_buffer = | 146 | sizeof(struct scu_sgl_element_pair)); |
152 | scic_sds_stp_request_get_sgl_element_buffer(this_request); | 147 | |
153 | this_request->parent.sgl_element_pair_buffer = | 148 | if (sci_req->was_tag_assigned_by_user == false) { |
154 | scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer); | 149 | sci_req->task_context_buffer = |
155 | 150 | scic_sds_stp_request_get_task_context_buffer(stp_req); | |
156 | if (this_request->parent.was_tag_assigned_by_user == false) { | 151 | sci_req->task_context_buffer = PTR_ALIGN(sci_req->task_context_buffer, |
157 | this_request->parent.task_context_buffer = | 152 | SMP_CACHE_BYTES); |
158 | scic_sds_stp_request_get_task_context_buffer(this_request); | ||
159 | this_request->parent.task_context_buffer = | ||
160 | scic_sds_request_align_task_context_buffer(this_request->parent.task_context_buffer); | ||
161 | } | 153 | } |
162 | } | 154 | } |
163 | 155 | ||