1. 28 7月, 2010 11 次提交
    • J
      [SCSI] libfc: add fc_fill_reply_hdr() and fc_fill_hdr() · 24f089e2
      Joe Eykholt 提交于
      Add functions to fill in an FC header given a request header.
      These reduces code lines in fc_lport and fc_rport and works
      without an exchange/sequence assigned.
      
      fc_fill_reply_hdr() fills a header for a final reply frame.
      
      fc_fill_hdr() which is similar but allows specifying the
      f_ctl parameter.
      
      Add defines for F_CTL values FC_FCTL_REQ and FC_FCTL_RESP.
      These can be used for most request and response sequences.
      
      v2 of patch adds a line to copy the frame encapsulation
      info from the received frame.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      24f089e2
    • J
      [SCSI] libfc: add fc_frame_sid() and fc_frame_did() functions · 251748a9
      Joe Eykholt 提交于
      To pave the way for eliminating exchanges from incoming requests,
      add simple inline fc_frame_sid() and fc_frame_did() functions
      which get the FC_IDs from the frame header.  This can be almost
      as efficient as getting them from the sequence/exchange.
      
      Move ntohll, htonll, ntoh24 and hton24 to <scsi/fc_frame.h>
      since we need them there and that's included by <scsi/libfc.h>
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      251748a9
    • J
      [SCSI] libfc: eliminate rport LOGO state · 079ecd8c
      Joe Eykholt 提交于
      The LOGO state hasn't been used in a while, except in a brief
      transition to DELETE state while holding the rport mutex.
      All port LOGO responses have been ignored as well as any timeout
      if we don't get a response.
      
      So this patch just removes LOGO state and simplifies the response handler.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      079ecd8c
    • J
      [SCSI] libfc: track FIP exchanges · f60e12e9
      Joe Eykholt 提交于
      When an exchange is received with a FIP encapsulation, we need
      to know that the response must be sent via FIP and what the original
      ELS opcode was.  This becomes important for VN2VN mode, where we may
      receive FLOGI or LOGO from several peer VN_ports, and the LS_ACC or
      LS_RJT must be sent FIP-encapsulated with the correct sub-type.
      
      Add a field to the struct fc_frame, fr_encaps, to indicate the
      encapsulation values.  That term is chosen to be neutral and
      LLD-agnostic in case non-FCoE/FIP LLDs might find it useful.
      
      The frame fr_encaps is transferred from the ingress frame to the
      exchange by fc_exch_recv_req(), and back to the outgoing frame
      by fc_seq_send().
      
      This is taking the last byte in the skb->cb array.  If needed,
      we could combine the info in sof, eof, flags, and encaps
      together into one field, but it'd be better to do that if
      and when its needed.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      f60e12e9
    • J
      [SCSI] libfc: add FLOGI state to rport for VN2VN · a7b12a27
      Joe Eykholt 提交于
      The FIP proposal for VN_port to VN_port point-to-multipoint
      operation requires a FLOGI be sent to each remote port.
      The FLOGI is sent with the assigned S_ID and D_IDs of the
      local and remote ports.  This and the response get
      FIP-encapsulated for Ethernet.
      
      Add FLOGI state to the remote port state machine.
      This will be skipped if not in point-to-multipoint mode.
      
      To reduce a little duplication between PLOGI and FLOGI
      response handling, added fc_rport_login_complete(), which
      handles the parameters for the rdata struct.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      a7b12a27
    • J
      [SCSI] libfc: Add local port point-to-multipoint flag · 3726f358
      Joe Eykholt 提交于
      For VN_port to VN_port mode, the transport sets the port_id and
      there's no lport FLOGI.  This is similar to FC loop mode.
      
      Add a point_to_multipoint flag that indicates the local port is in
      point-to-multipoint mode.  This skips FLOGI and discovery.
      It also skips resetting the port_id on resets other than link down.
      
      Add function fc_lport_set_local_id() that sets the local port_id.
      This is called by libfcoe on behalf of the low-level driver
      to set the port_id when the link comes up.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      3726f358
    • J
      [SCSI] libfc: add discovery-private pointer for LLD · 0685230c
      Joe Eykholt 提交于
      For VN_port to VN_port mode, FIP will do discovery and needs a
      way to find its state from the local port or discovery structure.
      It seems that any other LLD that implements its own discovery
      would also need something like this.
      
      Replace disc->lport with disc->priv, and use container_of to
      find the lport.  We could use disc->priv for that, but
      container_of is smaller and faster.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      0685230c
    • J
      [SCSI] libfc: provide space for LLD after remote port structure · f90377ab
      Joe Eykholt 提交于
      Add pre-zeroed space after the allocation for fc_rport_priv
      for use by the lower-level driver.
      
      This is primarily for VN2VN FIP mode, but could be used in
      other ways someday.
      
      The space required is specified in lport->rport_priv_size.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      f90377ab
    • J
      [SCSI] libfc: convert rport lookup to be RCU safe · 42e90414
      Joe Eykholt 提交于
      To allow LLD to do lookups on rports without grabbing a mutex,
      make them RCU-safe.  The caller of lport->tt.rport_lookup will
      have the choice of holding disc_mutex or the rcu_read_lock().
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      42e90414
    • J
      [SCSI] libfc: fix indefinite rport restart · f034260d
      Joe Eykholt 提交于
      Remote ports were restarting indefinitely after getting
      rejects in PRLI.
      
      Fix by adding a counter of restarts and limiting that with
      the port login retry limit as well.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      f034260d
    • J
      [SCSI] libfc: Fix remote port restart problem · 4b2164d4
      Joe Eykholt 提交于
      This patch somewhat combines two fixes to remote port handing in libfc.
      
      The first problem was that rport work could be queued on a deleted
      and freed rport.  This is handled by not resetting rdata->event
      ton NONE if the rdata is about to be deleted.
      
      However, that fix led to the second problem, described by
      Bhanu Gollapudi, as follows:
      > Here is the sequence of events. T1 is first LOGO receive thread, T2 is
      > fc_rport_work() scheduled by T1 and T3 is second LOGO receive thread and
      > T4 is fc_rport_work scheduled by T3.
      >
      > 1. (T1)Received 1st LOGO in state Ready
      > 2. (T1)Delete port & enter to RESTART state.
      > 3. (T1)schdule event_work, since event is RPORT_EV_NONE.
      > 4. (T1)set event = RPORT_EV_LOGO
      > 5. (T1)Enter RESTART state as disc_id is set.
      > 6. (T2)remember to PLOGI, and set event = RPORT_EV_NONE
      > 6. (T3)Received 2nd LOGO
      > 7. (T3)Delete Port & enter to RESTART state.
      > 8. (T3)schedule event_work, since event is RPORT_EV_NONE.
      > 9. (T3)Enter RESTART state as disc_id is set.
      > 9. (T3)set event = RPORT_EV_LOGO
      > 10.(T2)work restart, enter PLOGI state and issues PLOGI
      > 11.(T4)Since state is not RESTART anymore, restart is not set, and the
      > event is not reset to RPORT_EV_NONE. (current event is RPORT_EV_LOGO).
      > 12. Now, PLOGI succeeds and fc_rport_enter_ready() will not schedule
      > event_work, and hence the rport will never be created, eventually losing
      > the target after dev_loss_tmo.
      
      So, the problem here is that we were tracking the desire for
      the rport be restarted by state RESTART, which was otherwise
      equivalent to DELETE.  A contributing factor is that we dropped
      the lock between steps 6 and 10 in thread T2, which allows the
      state to change, and we didn't completely re-evaluate then.
      
      This is hopefully corrected by the following minor redesign:
      
      Simplify the rport restart logic by making the decision to
      restart after deleting the transport rport.  That decision
      is based on a new STARTED flag that indicates fc_rport_login()
      has been called and fc_rport_logoff() has not been called
      since then.  This replaces the need for the RESTART state.
      
      Only restart if the rdata is still in DELETED state
      and only if it still has the STARTED flag set.
      
      Also now, since we clear the event code much later in the
      work thread, allow for the possibility that the rport may
      have become READY again via incoming PLOGI, and if so,
      queue another event to handle that.
      
      In the problem scenario, the second LOGO received will
      cause the LOGO event to occur again.
      Reported-by: NBhanu Gollapudi <bprakash@broadcom.com>
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      4b2164d4
  2. 17 5月, 2010 2 次提交
  3. 12 4月, 2010 1 次提交
  4. 11 4月, 2010 1 次提交
    • J
      [SCSI] libfc, libfcoe, fcoe: use smp_processor_id() only when preempt disabled · f018b73a
      Joe Eykholt 提交于
      When the kernel is configured for preemption, using smp_processor_id()
      when preemption is enabled causes a warning backtrace and is wrong
      since we could move off of that CPU as soon as we get the ID,
      and we would be referencing the wrong CPU, and possibly an invalid one
      if it could be hotswapped out.
      
      Remove the fc_lport_get_stats() function and explicitly use per_cpu_ptr()
      to get the statistics.  Where preemption has been disabled by holding
      a _bh lock continue to use smp_processor_id(), but otherwise use
      get_cpu()/put_cpu().
      
      In fcoe_recv_frame() also changed the cases where we return in the
      middle to do a goto to the code which bumps ErrorFrames and does
      a put_cpu().  Two of these cases didn't bump ErrorFrames before, but
      doing so is harmless because they "can't happen", due to prior length
      checks.
      
      Also rearranged code in fcoe_recv_frame() to have only one call to
      fc_exch_recv().  It's just as efficient and saves a call to put_cpu().
      
      In fc_fcp.c, adjusted a FIXME comment for code which doesn't need fixing.
      Signed-off-by: NJoe Eykholt <jeykholt@cisco.com>
      Signed-off-by: NRobert Love <robert.w.love@intel.com>
      Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
      f018b73a
  5. 05 12月, 2009 20 次提交
  6. 11 9月, 2009 5 次提交