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 <[email protected]>
Signed-off-by: Jacek Danecki <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
return sizeof(struct scic_sds_request)
+ scic_ssp_io_request_get_object_size()
+ sizeof(struct scu_task_context)
- + CACHE_LINE_SIZE
+ + SMP_CACHE_BYTES
+ sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS;
}
this_request->sgl_element_pair_buffer =
scic_sds_ssp_request_get_sgl_element_buffer(this_request);
this_request->sgl_element_pair_buffer =
- scic_sds_request_align_sgl_element_buffer(this_request->sgl_element_pair_buffer);
+ PTR_ALIGN(this_request->sgl_element_pair_buffer,
+ sizeof(struct scu_sgl_element_pair));
if (this_request->was_tag_assigned_by_user == false) {
this_request->task_context_buffer =
scic_sds_ssp_request_get_task_context_buffer(this_request);
this_request->task_context_buffer =
- scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
+ PTR_ALIGN(this_request->task_context_buffer,
+ SMP_CACHE_BYTES);
}
}
this_request->task_context_buffer =
scic_sds_ssp_task_request_get_task_context_buffer(this_request);
this_request->task_context_buffer =
- scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
+ PTR_ALIGN(this_request->task_context_buffer, SMP_CACHE_BYTES);
}
}
#define scic_sds_request_get_task_context(request) \
((request)->task_context_buffer)
-#define CACHE_LINE_SIZE (64)
-#define scic_sds_request_align_task_context_buffer(address) \
- ((struct scu_task_context *)(\
- (((unsigned long)(address)) + (CACHE_LINE_SIZE - 1)) \
- & ~(CACHE_LINE_SIZE - 1) \
- ))
-
-/**
- * scic_sds_request_align_sgl_element_buffer() -
- *
- * This macro will align the memory address so that it is correct for the SCU
- * hardware to DMA the SGL element pairs.
- */
-#define scic_sds_request_align_sgl_element_buffer(address) \
- ((struct scu_sgl_element_pair *)(\
- ((char *)(address)) \
- + (\
- ((~(unsigned long)(address)) + 1) \
- & (sizeof(struct scu_sgl_element_pair) - 1) \
- ) \
- ))
-
/**
* scic_sds_request_set_status() -
*
return sizeof(struct scic_sds_request)
+ sizeof(struct smp_request)
+ sizeof(struct smp_response)
- + sizeof(struct scu_task_context);
+ + sizeof(struct scu_task_context)
+ + SMP_CACHE_BYTES;
}
/**
this_request->task_context_buffer =
scic_sds_smp_request_get_task_context_buffer(this_request);
this_request->task_context_buffer =
- scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
+ PTR_ALIGN(this_request->task_context_buffer, SMP_CACHE_BYTES);
}
}
+ sizeof(struct sata_fis_reg_h2d)
+ sizeof(struct sata_fis_reg_d2h)
+ sizeof(struct scu_task_context)
+ + SMP_CACHE_BYTES
+ sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS;
}
-/**
- *
- *
- *
- */
-void scic_sds_stp_request_assign_buffers(
- struct scic_sds_request *request)
+void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req)
{
- struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
-
- this_request->parent.command_buffer =
- scic_sds_stp_request_get_h2d_reg_buffer(this_request);
- this_request->parent.response_buffer =
- scic_sds_stp_request_get_response_buffer(this_request);
- this_request->parent.sgl_element_pair_buffer =
- scic_sds_stp_request_get_sgl_element_buffer(this_request);
- this_request->parent.sgl_element_pair_buffer =
- scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer);
-
- if (this_request->parent.was_tag_assigned_by_user == false) {
- this_request->parent.task_context_buffer =
- scic_sds_stp_request_get_task_context_buffer(this_request);
- this_request->parent.task_context_buffer =
- scic_sds_request_align_task_context_buffer(this_request->parent.task_context_buffer);
+ struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent);
+
+ sci_req->command_buffer = scic_sds_stp_request_get_h2d_reg_buffer(stp_req);
+ sci_req->response_buffer = scic_sds_stp_request_get_response_buffer(stp_req);
+ sci_req->sgl_element_pair_buffer = scic_sds_stp_request_get_sgl_element_buffer(stp_req);
+ sci_req->sgl_element_pair_buffer = PTR_ALIGN(sci_req->sgl_element_pair_buffer,
+ sizeof(struct scu_sgl_element_pair));
+
+ if (sci_req->was_tag_assigned_by_user == false) {
+ sci_req->task_context_buffer =
+ scic_sds_stp_request_get_task_context_buffer(stp_req);
+ sci_req->task_context_buffer = PTR_ALIGN(sci_req->task_context_buffer,
+ SMP_CACHE_BYTES);
}
}