[PATCH 7/7 v2] nvme-fabrics: Add FC LLDD loopback driver to test FC-NVME
James Smart
james.smart at broadcom.com
Wed Oct 12 13:12:34 PDT 2016
On 10/12/2016 3:37 AM, Christoph Hellwig wrote:
>> +#define is_end_of_list(pos, head, member) ((&pos->member) == (head))
> This one isn't actually used in the code.
Yep. I realize I removed it in the last rework.
>
>> +int
>> +fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
>> + struct nvmefc_tgt_fcp_req *tgt_fcpreq)
>> +{
>> + struct fcloop_fcpreq *tfcp_req = tgt_fcp_req_to_fcpreq(tgt_fcpreq);
>> + struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq;
>> + u32 rsplen = 0, xfrlen = 0;
>> + int fcp_err = 0;
>> + u8 op = tgt_fcpreq->op;
>> +
>> + switch (op) {
>> + case NVMET_FCOP_WRITEDATA:
>> + xfrlen = tgt_fcpreq->transfer_length;
>> + fcloop_fcp_copy_data(op, tgt_fcpreq->sg, fcpreq->first_sgl,
>> + tgt_fcpreq->offset, xfrlen);
>> + fcpreq->transferred_length += xfrlen;
> .. but I don't even understand why we need to copy between these
> SGLs?
You've lost me. The fc-nvme api on the initiator side has a sgl relative
to the original io request, while the fc-nvmet api on the target side
has a different sgl from the target fc-nvme transport to the LLDD for
the range of data to exchange. They are sgl's as they expect to go to fc
hw on each side. As they are independent sgl's on each side, we have to
copy between them.
>
>> + spin_lock_irqsave(&fcloop_lock, flags);
>> +
>> + list_for_each_entry(tlport, &fcloop_lports, lport_list) {
>> + if ((tlport->localport->node_name == nodename) &&
>> + (tlport->localport->port_name == portname)) {
>> + lport = tlport;
>> + break;
>> + }
>> + }
>> + spin_unlock_irqrestore(&fcloop_lock, flags);
>> +
>> + if (!lport)
>> + return -ENOENT;
>> +
>> + ret = __delete_local_port(lport);
> We either need a reference or do the actual deletion under the
> lock.
Well, there are only 2 conditions it matters - the user invokes the
sysfs point twice for the same port, or sysfs and module unload occur at
the same time. I guess I assumed both of these to be operator issues.
But it's no big deal to address them. Yes - same conditions occurs on
the other port delete calls.
>
>> +
>> + fcloop_device =
>> + device_create(fcloop_class, NULL, MKDEV(0, 0), NULL, "ctl");
>> + if (IS_ERR(fcloop_device)) {
>> + pr_err("couldn't create ctl device!\n");
>> + ret = PTR_ERR(fcloop_device);
>> + goto out_destroy_class;
>> + }
>> +
>> + ret = device_create_file(fcloop_device, &dev_attr_add_local_port);
>> + if (ret) {
>> + pr_err("couldn't add device add_local_port attr.\n");
>> + goto out_destroy_device;
>> + }
>> +
>> + ret = device_create_file(fcloop_device, &dev_attr_del_local_port);
> ...
>
> Please use device_create_with_groups.
ok
>
>> + for (;;) {
>> + nport = list_first_entry_or_null(&fcloop_nports,
>> + typeof(*nport), nport_list);
>> + if (!nport)
>> + break;
>> +
>> + spin_unlock_irqrestore(&fcloop_lock, flags);
>> +
>> + ret = __delete_target_port(nport);
>> + if (ret)
>> + pr_warn("%s: Failed deleting target port\n", __func__);
>> +
>> + ret = __delete_remote_port(nport);
>> + if (ret)
>> + pr_warn("%s: Failed deleting remote port\n", __func__);
>> +
>> + spin_lock_irqsave(&fcloop_lock, flags);
>> + }
> The deletions need to happen without dropping the lock, or you need
> refcounts.
yes - I'll address it.
Ok to the other comments
-- james
More information about the Linux-nvme
mailing list