Skip to content

Commit

Permalink
[SCSI] libsas: replace event locks with atomic bitops
Browse files Browse the repository at this point in the history
The locks only served to make sure the pending event bitmask was updated
consistently.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Dan Williams authored and James Bottomley committed Feb 19, 2012
1 parent 756f173 commit b15ebe0
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 60 deletions.
10 changes: 3 additions & 7 deletions drivers/scsi/libsas/sas_discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ static void sas_discover_domain(struct work_struct *work)
container_of(work, struct sas_discovery_event, work);
struct asd_sas_port *port = ev->port;

sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock,
&port->disc.pending);
clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending);

if (port->port_dev)
return;
Expand Down Expand Up @@ -355,8 +354,7 @@ static void sas_revalidate_domain(struct work_struct *work)
container_of(work, struct sas_discovery_event, work);
struct asd_sas_port *port = ev->port;

sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock,
&port->disc.pending);
clear_bit(DISCE_REVALIDATE_DOMAIN, &port->disc.pending);

SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
task_pid_nr(current));
Expand All @@ -379,8 +377,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)

BUG_ON(ev >= DISC_NUM_EVENTS);

sas_queue_event(ev, &disc->disc_event_lock, &disc->pending,
&disc->disc_work[ev].work, port->ha);
sas_queue_event(ev, &disc->pending, &disc->disc_work[ev].work, port->ha);

return 0;
}
Expand All @@ -400,7 +397,6 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
[DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
};

spin_lock_init(&disc->disc_event_lock);
disc->pending = 0;
for (i = 0; i < DISC_NUM_EVENTS; i++) {
INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
Expand Down
8 changes: 3 additions & 5 deletions drivers/scsi/libsas/sas_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event)
{
BUG_ON(event >= HA_NUM_EVENTS);

sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending,
sas_queue_event(event, &sas_ha->pending,
&sas_ha->ha_events[event].work, sas_ha);
}

Expand All @@ -40,7 +40,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)

BUG_ON(event >= PORT_NUM_EVENTS);

sas_queue_event(event, &ha->event_lock, &phy->port_events_pending,
sas_queue_event(event, &phy->port_events_pending,
&phy->port_events[event].work, ha);
}

Expand All @@ -50,7 +50,7 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)

BUG_ON(event >= PHY_NUM_EVENTS);

sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending,
sas_queue_event(event, &phy->phy_events_pending,
&phy->phy_events[event].work, ha);
}

Expand All @@ -62,8 +62,6 @@ int sas_init_events(struct sas_ha_struct *sas_ha)

int i;

spin_lock_init(&sas_ha->event_lock);

for (i = 0; i < HA_NUM_EVENTS; i++) {
INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]);
sas_ha->ha_events[i].ha = sas_ha;
Expand Down
3 changes: 1 addition & 2 deletions drivers/scsi/libsas/sas_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ void sas_hae_reset(struct work_struct *work)
container_of(work, struct sas_ha_event, work);
struct sas_ha_struct *ha = ev->ha;

sas_begin_event(HAE_RESET, &ha->event_lock,
&ha->pending);
clear_bit(HAE_RESET, &ha->pending);
}

int sas_register_ha(struct sas_ha_struct *sas_ha)
Expand Down
32 changes: 7 additions & 25 deletions drivers/scsi/libsas/sas_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,36 +92,18 @@ static inline int sas_smp_host_handler(struct Scsi_Host *shost,
}
#endif

static inline void sas_queue_event(int event, spinlock_t *lock,
unsigned long *pending,
static inline void sas_queue_event(int event, unsigned long *pending,
struct work_struct *work,
struct sas_ha_struct *sas_ha)
{
unsigned long flags;
if (!test_and_set_bit(event, pending)) {
unsigned long flags;

spin_lock_irqsave(lock, flags);
if (test_bit(event, pending)) {
spin_unlock_irqrestore(lock, flags);
return;
spin_lock_irqsave(&sas_ha->state_lock, flags);
if (sas_ha->state != SAS_HA_UNREGISTERED)
scsi_queue_work(sas_ha->core.shost, work);
spin_unlock_irqrestore(&sas_ha->state_lock, flags);
}
__set_bit(event, pending);
spin_unlock_irqrestore(lock, flags);

spin_lock_irqsave(&sas_ha->state_lock, flags);
if (sas_ha->state != SAS_HA_UNREGISTERED) {
scsi_queue_work(sas_ha->core.shost, work);
}
spin_unlock_irqrestore(&sas_ha->state_lock, flags);
}

static inline void sas_begin_event(int event, spinlock_t *lock,
unsigned long *pending)
{
unsigned long flags;

spin_lock_irqsave(lock, flags);
__clear_bit(event, pending);
spin_unlock_irqrestore(lock, flags);
}

static inline void sas_fill_in_rphy(struct domain_device *dev,
Expand Down
12 changes: 4 additions & 8 deletions drivers/scsi/libsas/sas_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work)
container_of(work, struct asd_sas_event, work);
struct asd_sas_phy *phy = ev->phy;

sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
&phy->phy_events_pending);
clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending);
phy->error = 0;
sas_deform_port(phy, 1);
}
Expand All @@ -48,8 +47,7 @@ static void sas_phye_oob_done(struct work_struct *work)
container_of(work, struct asd_sas_event, work);
struct asd_sas_phy *phy = ev->phy;

sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock,
&phy->phy_events_pending);
clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending);
phy->error = 0;
}

Expand All @@ -63,8 +61,7 @@ static void sas_phye_oob_error(struct work_struct *work)
struct sas_internal *i =
to_sas_internal(sas_ha->core.shost->transportt);

sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock,
&phy->phy_events_pending);
clear_bit(PHYE_OOB_ERROR, &phy->phy_events_pending);

sas_deform_port(phy, 1);

Expand Down Expand Up @@ -95,8 +92,7 @@ static void sas_phye_spinup_hold(struct work_struct *work)
struct sas_internal *i =
to_sas_internal(sas_ha->core.shost->transportt);

sas_begin_event(PHYE_SPINUP_HOLD, &phy->ha->event_lock,
&phy->phy_events_pending);
clear_bit(PHYE_SPINUP_HOLD, &phy->phy_events_pending);

phy->error = 0;
i->dft->lldd_control_phy(phy, PHY_FUNC_RELEASE_SPINUP_HOLD, NULL);
Expand Down
15 changes: 5 additions & 10 deletions drivers/scsi/libsas/sas_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ void sas_porte_bytes_dmaed(struct work_struct *work)
container_of(work, struct asd_sas_event, work);
struct asd_sas_phy *phy = ev->phy;

sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock,
&phy->port_events_pending);
clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending);

sas_form_port(phy);
}
Expand All @@ -227,8 +226,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work)
unsigned long flags;
u32 prim;

sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock,
&phy->port_events_pending);
clear_bit(PORTE_BROADCAST_RCVD, &phy->port_events_pending);

spin_lock_irqsave(&phy->sas_prim_lock, flags);
prim = phy->sas_prim;
Expand All @@ -244,8 +242,7 @@ void sas_porte_link_reset_err(struct work_struct *work)
container_of(work, struct asd_sas_event, work);
struct asd_sas_phy *phy = ev->phy;

sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
&phy->port_events_pending);
clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending);

sas_deform_port(phy, 1);
}
Expand All @@ -256,8 +253,7 @@ void sas_porte_timer_event(struct work_struct *work)
container_of(work, struct asd_sas_event, work);
struct asd_sas_phy *phy = ev->phy;

sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
&phy->port_events_pending);
clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending);

sas_deform_port(phy, 1);
}
Expand All @@ -268,8 +264,7 @@ void sas_porte_hard_reset(struct work_struct *work)
container_of(work, struct asd_sas_event, work);
struct asd_sas_phy *phy = ev->phy;

sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
&phy->port_events_pending);
clear_bit(PORTE_HARD_RESET, &phy->port_events_pending);

sas_deform_port(phy, 1);
}
Expand Down
3 changes: 0 additions & 3 deletions include/scsi/libsas.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ struct sas_discovery_event {
};

struct sas_discovery {
spinlock_t disc_event_lock;
struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
unsigned long pending;
u8 fanout_sas_addr[8];
Expand Down Expand Up @@ -272,7 +271,6 @@ struct asd_sas_event {
*/
struct asd_sas_phy {
/* private: */
/* protected by ha->event_lock */
struct asd_sas_event port_events[PORT_NUM_EVENTS];
struct asd_sas_event phy_events[PHY_NUM_EVENTS];

Expand Down Expand Up @@ -337,7 +335,6 @@ enum sas_ha_state {

struct sas_ha_struct {
/* private: */
spinlock_t event_lock;
struct sas_ha_event ha_events[HA_NUM_EVENTS];
unsigned long pending;

Expand Down

0 comments on commit b15ebe0

Please sign in to comment.