Example #1
0
static void _about_to_complete_local_write(struct drbd_conf *mdev,
	struct drbd_request *req)
{
	const unsigned long s = req->rq_state;
	struct drbd_request *i;
	struct drbd_epoch_entry *e;
	struct hlist_node *n;
	struct hlist_head *slot;

	/* before we can signal completion to the upper layers,
	 * we may need to close the current epoch */
	if (mdev->state.conn >= C_CONNECTED &&
	    req->epoch == mdev->newest_tle->br_number)
		queue_barrier(mdev);

	/* we need to do the conflict detection stuff,
	 * if we have the ee_hash (two_primaries) and
	 * this has been on the network */
	if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) {
		const sector_t sector = req->sector;
		const int size = req->size;

		/* ASSERT:
		 * there must be no conflicting requests, since
		 * they must have been failed on the spot */
#define OVERLAPS overlaps(sector, size, i->sector, i->size)
		slot = tl_hash_slot(mdev, sector);
		hlist_for_each_entry(i, n, slot, colision) {
			if (OVERLAPS) {
				dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
				      "other: %p %llus +%u\n",
				      req, (unsigned long long)sector, size,
				      i, (unsigned long long)i->sector, i->size);
			}
		}

		/* maybe "wake" those conflicting epoch entries
		 * that wait for this request to finish.
		 *
		 * currently, there can be only _one_ such ee
		 * (well, or some more, which would be pending
		 * P_DISCARD_ACK not yet sent by the asender...),
		 * since we block the receiver thread upon the
		 * first conflict detection, which will wait on
		 * misc_wait.  maybe we want to assert that?
		 *
		 * anyways, if we found one,
		 * we just have to do a wake_up.  */
#undef OVERLAPS
#define OVERLAPS overlaps(sector, size, e->sector, e->size)
		slot = ee_hash_slot(mdev, req->sector);
		hlist_for_each_entry(e, n, slot, colision) {
			if (OVERLAPS) {
				wake_up(&mdev->misc_wait);
				break;
			}
		}
	}
#undef OVERLAPS
}
Example #2
0
void stop_loop_usparcIIs(int branchno,int counter)
{
  queue_load_addr(counter,Hdecrement,counter);
/*Wasting one Iop here - could set condition code with addcc*/
  queue_barrier();
  make_inst(IALUPIPE,IOR_PREDICATE,counter,counter,counter);
  make_inst(BRCHPIPE,BRANCH_GT,branchno);
}
Example #3
0
void stop_loop_powerIII(int branchno,int counter)
{
  /* Use the auto decrementing branch if possible */
  queue_load_addr(counter,Hdecrement,counter);
  if ( innermost ) {
    make_inst(BRCHPIPE,BRANCH_CTR,branchno);
    innermost = 0;
  }
  else {
    queue_barrier();
    make_inst(IALUPIPE,IOR_PREDICATE,counter,counter,counter); /*Sets the predicate reg*/
    make_inst(BRCHPIPE,BRANCH_GT,branchno);
  }
  return;
}
Example #4
0
static void _about_to_complete_local_write(struct drbd_conf *mdev,
	struct drbd_request *req)
{
	const unsigned long s = req->rq_state;
	struct drbd_request *i;
	struct drbd_epoch_entry *e;
	struct hlist_node *n;
	struct hlist_head *slot;

	if (mdev->state.conn >= C_CONNECTED &&
	    (s & RQ_NET_SENT) != 0 &&
	    req->epoch == mdev->newest_tle->br_number)
		queue_barrier(mdev);

	if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) {
		const sector_t sector = req->sector;
		const int size = req->size;

#define OVERLAPS overlaps(sector, size, i->sector, i->size)
		slot = tl_hash_slot(mdev, sector);
		hlist_for_each_entry(i, n, slot, collision) {
			if (OVERLAPS) {
				dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
				      "other: %p %llus +%u\n",
				      req, (unsigned long long)sector, size,
				      i, (unsigned long long)i->sector, i->size);
			}
		}

#undef OVERLAPS
#define OVERLAPS overlaps(sector, size, e->sector, e->size)
		slot = ee_hash_slot(mdev, req->sector);
		hlist_for_each_entry(e, n, slot, collision) {
			if (OVERLAPS) {
				wake_up(&mdev->misc_wait);
				break;
			}
		}
	}
#undef OVERLAPS
}