On Tue, 2009-06-02 at 16:09 -0700, Joe Eykholt wrote:
> >>> +
> >>> +/*
> >>> + * Reset exchange managers, releasing all sequences and
> exchanges.
> >>> + * If sid is non-zero, reset only exchanges we source from that
> FID.
> >>> + * If did is non-zero, reset only exchanges destined to that FID.
> >>> + */
> >>> +void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did)
> >>> +{
> >>> +   fc_exch_em_reset(lp, lp->emp, sid, did);
> >>> +   if (lp->oemp)
> >>> +           fc_exch_em_reset(lp, lp->oemp, sid, did);
> >>> +}
> >>>  EXPORT_SYMBOL(fc_exch_mgr_reset);
> >> This is OK, but another way to do this is to have the fcoe LLD
> implement
> >> the transport pointer for fc_exch_mgr_reset() and call
> fc_exch_mgr_reset()
> >> for both EMs.
> >>
> >> That way, other LLDs that don't offload, or offload differently,
> >> wouldn't be exposed to oemp.  Oemp could just be in fcoe_softc, and
> not
> >> in the local port.
> >>
> > 
> > Make sense to redo this another way suggested above for reasons
> > mentioned by you above, I started with em_list in my initial post
> with
> > intent to have just one common reset for shared oemp or non-shared
> > lp->emp but later realized that won't work for shared oemp as oemp
> > cannot be put on two lists with one list_head, so we can't have
> common
> > reset code that way for oemp. So I'll move above  oemp reset code to
> > fcoe.ko.
> > 

We had internal discussion among mainly Rob, Chris and myself to
evaluate above discussed approach verses previously mentioned other
design option/approach of a generic EM list in libfc to implement this
feature of sharing offload EM instance across multiple lport on a eth
device. 

In that discussion we were able to list some pros and cons of these two
options with additional design details of each approach. I'm listing
those details below and would appreciate to have more review feedback on
them before implementing shared offload EM(SOEM) feature in this patch
series.  

Below is brief description of each option/approach :-

1. list of EMs in libfc lport. 

Have a list of ordered EM list for each lport using a anchor instance,
the anchor instance unique to each list node will allow a single SOEM
addition on more than one lport's EM list, the anchor will also contain
match function unique to a type of EM  (e.g. shared or not shared
default EM for now), so anchor would be like :

        struct fc_em_anchor {
                struct list_head *list;
                struct fc_exch_mgr *em;
                struct int  (*fc_em_match)(struct fc_lport *, 
                                           struct fc_frame *);
        }

       Build EM list such that SOEM first and then other default EM
instance, the SOEM will have match func to return true for read types of
IO to allow  DDP setup while default EM will have null match func
fc_em_match.

The SOEM will manage offload exchanges and rest all exchanges will be
managed by other EM in the list.

A new exch allocation will traverse the list and will try allocating
exch from SOEM first for true return value from fc_em_match and if it
fails then will allocate exch from next default EM in the list.

       Currently on the RX path, the fc_exch_recv() is called from
fcoe.ko with EM instance specified by fcoe.ko for each incoming frame,
that need to be modified to only pass up lp and received frame and then
have fc_exch_recv() locate EM instance by walking over the list of EM of
specified lport to do rest of the RX path processing.

2. Implement SOEM in fcoe.ko.

   This would be as discussed in this email thread before by having
fcoe_softc instance point to shared SOEM using a simple fc_exch_mgr
pointer and then allocate new exch  using either SOEM  or default
lp->emp in exch_get interface of lport libfc_function_template. 

The incoming frame's EM instance will be located by fcoe_exch_recv as
implemented in this patch series and then pass this up to libfc using
current fc_exch_recv API of libfc.

Above both approaches have pros and cons and we were able to come up
with this list of pros and cons between these approaches :-

1. Approach #1 will be more generic and extensible, approach #1 will
allow easily additions of more EM in future with their unique
fc_exch_match function implementation.

2. Approach #1 allows us to remove the exch_get from the
libfc_function_template lp->tt and no fear of ever-growing lp->tt.

3. Approach #1 will be complicate to implement compare to simpler
approach 2, this is due to additional EM list and EM lookup in TX and RX
path for approach #1  with additional list managements using
fc_exch_anchors.

4. We believe that performance is not a factor between these two
approaches, though #1 will have additional indirection for each new exch
allocation and EM lookup for a incoming frame, however not sure how
expensive that would be since potentially approach #1 will not require a
lock in traversing EM list on fast path and additional indirection
should not make any noticeable difference to performance compare
approach #2 using exch_get and fcoe_exch_recv.

Rob's preference is option-1, but we would like to hear more opinions.
If there is no strong opinions one way or the other, I will proceed with
Rob's recommendation and implement option-1.


Thanks
Vasu


_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to