From: Mike Christie <michaelc@cs.wisc.edu>
To: Bhanu Gollapudi <bprakash@broadcom.com>
Cc: devel@open-fcoe.org, linux-scsi@vger.kernel.org, mchan@broadcom.com
Subject: Re: [v2 PATCH 3/5] bnx2fc: Broadcom FCoE Offload driver submission - part 1
Date: Thu, 13 Jan 2011 18:57:24 -0600 [thread overview]
Message-ID: <4D2F9F74.9030206@cs.wisc.edu> (raw)
In-Reply-To: <1293170553.4676.573.camel@ltsjc-bprakash2.corp.ad.broadcom.com>
You should add more informative emails subject names.
On 12/24/2010 12:02 AM, Bhanu Gollapudi wrote:
> +int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req)
> +{
> +
> + struct fc_els_rrq rrq;
> + struct bnx2fc_rport *tgt = aborted_io_req->tgt;
> + struct fc_lport *lport = tgt->rdata->local_port;
> + struct bnx2fc_els_cb_arg *cb_arg = NULL;
> + u32 sid = tgt->sid;
> + u32 r_a_tov = lport->r_a_tov;
> + int rc;
> +
> + bnx2fc_dbg(LOG_ELS, "Sending RRQ orig_xid = 0x%x\n",
> + aborted_io_req->xid);
> + memset(&rrq, 0, sizeof(rrq));
> +
> + cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
I think you can sleep in this path, right? It looks like it is run from
workqueue and no locks held. You probably want to use GFP_NOIO instead
of atomic then.
Change bnx2fc_send_adisc and bnx2fc_send_logo too then.
If you can't sleep in this path then you have a problem because they
call bnx2fc_initiate_els which sleeps when allocations fail.
> +
> +static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg)
> +{
> + struct bnx2fc_cmd *els_req;
> + struct bnx2fc_rport *tgt;
> + struct bnx2fc_mp_req *mp_req;
> + struct fc_frame_header *fc_hdr;
> + unsigned char *buf;
> + void *resp_buf;
> + u32 resp_len, hdr_len;
> + u16 l2_oxid;
> + int frame_len;
> + int rc = 0;
> +
> + l2_oxid = cb_arg->l2_oxid;
> + bnx2fc_dbg(LOG_ELS, "ELS COMPL - l2_oxid = 0x%x\n", l2_oxid);
> +
> + els_req = cb_arg->io_req;
> + if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT,&els_req->req_flags)) {
> + /*
> + * els req is timed out. cleanup the IO with FW and
> + * drop the completion. libfc will handle the els timeout
> + */
> + if (els_req->on_active_queue) {
> + list_del_init(&els_req->link);
> + els_req->on_active_queue = 0;
> + rc = bnx2fc_initiate_cleanup(els_req);
> + BUG_ON(rc);
> + }
> + goto free_arg;
> + }
> +
> + tgt = els_req->tgt;
> + mp_req =&(els_req->mp_req);
> + fc_hdr =&(mp_req->resp_fc_hdr);
> + resp_len = mp_req->resp_len;
> + resp_buf = mp_req->resp_buf;
> +
> + buf = kzalloc(0x1000, GFP_ATOMIC);
Where did the size value for the allocation come from? It is a little
scary in that it is hard coded and then you copy to it with no bounds
checks.
> diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> new file mode 100644
> index 0000000..6452b0f
> --- /dev/null
> +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> @@ -0,0 +1,1939 @@
> +/* bnx2fc_hwi.c: Broadcom NetXtreme II Linux FCoE offload driver.
> + *
Instead of adding that info about the driver in every file it would be
more helpful to put some info on the code in the file.
bnx2fc_hwi.c: Low level functions that interact with the bnx hardware
blah blah or something.
> + * bnx2fc_send_fw_fcoe_init_msg - initiates initial handshake with FCoE f/w
> + *
> + * @hba: adapter structure pointer
> + *
> + * Send down FCoE firmware init KWQEs which initiates the initial handshake
> + * with the f/w.
> + *
> + */
> +int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba)
> +{
> + struct fcoe_kwqe_init1 fcoe_init1;
> + struct fcoe_kwqe_init2 fcoe_init2;
> + struct fcoe_kwqe_init3 fcoe_init3;
> + struct kwqe *kwqe_arr[3];
> + int num_kwqes = 3;
> + int rc = 0;
> +
> + if (!hba->cnic) {
> + printk(KERN_ALERT PFX "hba->cnic NULL during fcoe fw init\n");
> + return -ENODEV;
> + }
> +
> + /* fill init1 KWQE */
> + memset(&fcoe_init1, 0x00, sizeof(struct fcoe_kwqe_init1));
> + fcoe_init1.hdr.op_code = FCOE_KWQE_OPCODE_INIT1;
> + fcoe_init1.hdr.flags = (FCOE_KWQE_LAYER_CODE<<
> + FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
> +
> + fcoe_init1.num_tasks = BNX2FC_MAX_TASKS;
> + fcoe_init1.sq_num_wqes = BNX2FC_SQ_WQES_MAX;
> + fcoe_init1.rq_num_wqes = BNX2FC_RQ_WQES_MAX;
> + fcoe_init1.rq_buffer_log_size = BNX2FC_RQ_BUF_LOG_SZ;
> + fcoe_init1.cq_num_wqes = BNX2FC_CQ_WQES_MAX;
> + fcoe_init1.dummy_buffer_addr_lo = (u32) hba->dummy_buf_dma;
> + fcoe_init1.dummy_buffer_addr_hi = (u32) ((u64)hba->dummy_buf_dma>> 32);
> + fcoe_init1.task_list_pbl_addr_lo = (u32) hba->task_ctx_bd_dma;
> + fcoe_init1.task_list_pbl_addr_hi =
> + (u32) ((u64) hba->task_ctx_bd_dma>> 32);
> + fcoe_init1.mtu = hba->netdev->mtu;
> +
> + fcoe_init1.flags = (PAGE_SHIFT<<
> + FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT);
> + fcoe_init1.flags |= (0<<
> + FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT);
Is that right? What does shifting zero supposed to do here?
> +
> +/**
> + * bnx2fc_fastpath_notification - process global event queue (KCQ)
> + *
> + * @hba: adapter structure pointer
> + * @new_cqe_kcqe: pointer to newly DMA'd KCQ entry
> + *
> + * Fast path event notification handler
> + */
> +static void bnx2fc_fastpath_notification(struct bnx2fc_hba *hba,
> + struct fcoe_kcqe *new_cqe_kcqe)
> +{
> + u32 conn_id = new_cqe_kcqe->fcoe_conn_id;
> + struct bnx2fc_rport *tgt =
> + (struct bnx2fc_rport *)hba->tgt_ofld_list[conn_id];
no case needed.
> +
> + if (!tgt) {
> + printk(KERN_ALERT PFX "conn_id 0x%x not valid\n", conn_id);
> + return;
> + }
> + bnx2fc_process_new_cqes(tgt);
> +}
> +
> +/**
> + * bnx2fc_process_ofld_cmpl - process FCoE session offload completion
> + *
> + * @hba: adapter structure pointer
> + * @ofld_kcqe: connection offload kcqe pointer
> + *
> + * handle session offload completion, enable the session if offload is
> + * successful.
> + */
> +static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba *hba,
> + struct fcoe_kcqe *ofld_kcqe)
> +{
> + struct bnx2fc_rport *tgt;
> + struct bnx2fc_port *port;
> + u32 conn_id;
> + u32 context_id;
> + int rc;
> +
> + conn_id = ofld_kcqe->fcoe_conn_id;
> + context_id = ofld_kcqe->fcoe_conn_context_id;
> + bnx2fc_dbg(LOG_SESS, "Entered ofld compl - context_id = 0x%x\n",
> + ofld_kcqe->fcoe_conn_context_id);
> + tgt = (struct bnx2fc_rport *)hba->tgt_ofld_list[conn_id];
No case needed. Did the tgt_ofld_list array change or am I looking at it
right? tgt_ofld_list is an array of struct bnx2fc_rport *, so no need to
cast, right. If I am right fix them all. I don't think I mentioned them all.
> + return;
No return needed. How about, just check the rest of the functions for
this and fix.
> +static void bnx2fc_process_fcoe_error(struct bnx2fc_hba *hba,
> + struct fcoe_kcqe *fcoe_err)
> +{
> +
> +
> +}
Just delete this.
> +
> +void bnx2fc_add_2_sq(struct bnx2fc_rport *tgt, u16 xid)
> +{
> + struct fcoe_sqe *sqe;
> +
> + sqe = (struct fcoe_sqe *)&tgt->sq[tgt->sq_prod_idx];
> +
No cast needed. Just check all the casts and if you are casting to/from
a void or casting to/from the same structs then no case needed.
> +
> +/**
> + * bnx2fc_setup_task_ctx - allocate and map task context
> + *
> + * @hba: pointer to adapter structure
> + *
> + * allocate memory for task context, and associated BD table to be used
> + * by firmware
> + *
> + */
> +int bnx2fc_setup_task_ctx(struct bnx2fc_hba *hba)
> +{
> + int rc = 0;
> + struct regpair *task_ctx_bdt;
> + dma_addr_t addr;
> + int i;
> +
> + /*
> + * Allocate task context bd table. A page size of bd table
> + * can map 256 buffers. Each buffer contains 32 task context
> + * entries. Hence the limit with one page is 8192 task context
> + * entries.
> + */
> + hba->task_ctx_bd_tbl = dma_alloc_coherent(&hba->pcidev->dev,
> + PAGE_SIZE,
> + &hba->task_ctx_bd_dma,
> + GFP_KERNEL);
> + if (!hba->task_ctx_bd_tbl) {
> + printk(KERN_ERR PFX "unable to allocate task context BDT\n");
> + rc = -1;
> + goto out;
> + }
> + memset(hba->task_ctx_bd_tbl, 0, PAGE_SIZE);
> +
> + /*
> + * Allocate task_ctx which is an array of pointers pointing to
> + * a page containing 32 task contexts
> + */
> + hba->task_ctx = kmalloc((BNX2FC_TASK_CTX_ARR_SZ * sizeof(void *)),
> + GFP_KERNEL);
> + if (!hba->task_ctx) {
> + printk(KERN_ERR PFX "unable to allocate task context array\n");
> + rc = -1;
> + goto out1;
> + }
> + memset(hba->task_ctx, 0, BNX2FC_TASK_CTX_ARR_SZ * sizeof(void *));
> +
Use kzalloc.
> + /*
> + * Allocate task_ctx_dma which is an array of dma addresses
> + */
> + hba->task_ctx_dma = kmalloc((BNX2FC_TASK_CTX_ARR_SZ *
> + sizeof(dma_addr_t)), GFP_KERNEL);
> + if (!hba->task_ctx_dma) {
> + printk(KERN_ERR PFX "unable to alloc context mapping array\n");
> + rc = -1;
> + goto out2;
> + }
> +
> + task_ctx_bdt = (struct regpair *)hba->task_ctx_bd_tbl;
> + for (i = 0; i< BNX2FC_TASK_CTX_ARR_SZ; i++) {
> +
> + hba->task_ctx[i] = dma_alloc_coherent(&hba->pcidev->dev,
> + PAGE_SIZE,
> + &hba->task_ctx_dma[i],
> + GFP_KERNEL);
> + if (!hba->task_ctx[i]) {
> + printk(KERN_ERR PFX "unable to alloc task context\n");
> + rc = -1;
> + goto out3;
> + }
I think you want a dma pool instead.
> + memset(hba->task_ctx[i], 0, PAGE_SIZE);
> + addr = (u64)hba->task_ctx_dma[i];
> + task_ctx_bdt->hi = (u64) addr>> 32;
> + task_ctx_bdt->lo = (u32) addr;
> + task_ctx_bdt++;
> + }
> + return 0;
> +
> +out3:
> + for (i = 0; i< BNX2FC_TASK_CTX_ARR_SZ; i++) {
> + if (hba->task_ctx[i]) {
> +
> + dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
> + hba->task_ctx[i], hba->task_ctx_dma[i]);
> + hba->task_ctx[i] = NULL;
> + }
> + }
> +
> + kfree(hba->task_ctx_dma);
> + hba->task_ctx_dma = NULL;
> +out2:
> + kfree(hba->task_ctx);
> + hba->task_ctx = NULL;
> +out1:
> + dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
> + hba->task_ctx_bd_tbl, hba->task_ctx_bd_dma);
> + hba->task_ctx_bd_tbl = NULL;
> +out:
> + return rc;
> +}
next prev parent reply other threads:[~2011-01-14 0:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-24 6:02 [v2 PATCH 3/5] bnx2fc: Broadcom FCoE Offload driver submission - part 1 Bhanu Gollapudi
2011-01-14 0:57 ` Mike Christie [this message]
2011-01-15 0:50 ` Bhanu Gollapudi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D2F9F74.9030206@cs.wisc.edu \
--to=michaelc@cs.wisc.edu \
--cc=bprakash@broadcom.com \
--cc=devel@open-fcoe.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mchan@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox