Пример #1
0
uint64_t
cch_cityhash64_with_seed (const char *buf, size_t len, uint64_t seed)
{
#ifdef HAVE_CITYHASH64WITHSEED
  return CityHash64WithSeed(buf, len, seed);
#else
  feature_failure(__func__);
#endif
}
Пример #2
0
static void
svc_dg_checksum(struct svc_req *req, void *data, size_t length)
{
	req->rq_cksum =
#if 1
	/* CithHash64 is -substantially- faster than crc32c from FreeBSD
	 * SCTP, so prefer it until fast crc32c bests it */
		CityHash64WithSeed(data, MIN(256, length), 103);
#else
		calculate_crc32c(0, data, MIN(256, length));
#endif
}
Пример #3
0
static void
compute_buffer_cksum(RECSTREAM *rstrm)
{
#if 1
    /* CithHash64 is -substantially- faster than crc32c from FreeBSD
     * SCTP, so prefer it until fast crc32c bests it */
    rstrm->cksum =
        CityHash64WithSeed(rstrm->in_base,
                           MIN(rstrm->cklen, rstrm->offset),
                           103);
#else
    rstrm->cksum = calculate_crc32c(0, rstrm->in_base,
                                    MIN(rstrm->cklen, rstrm->offset));
#endif
}
Пример #4
0
/**
 * @brief Find and reference a DRC to process the supplied svc_req.
 *
 * @param[in] req  The svc_req being processed.
 *
 * @return The ref'd DRC if sucessfully located, else NULL.
 */
static /* inline */ drc_t *
nfs_dupreq_get_drc(struct svc_req *req)
{
	enum drc_type dtype = get_drc_type(req);
	drc_t *drc = NULL;
	bool drc_check_expired = false;

	switch (dtype) {
	case DRC_UDP_V234:
		LogFullDebug(COMPONENT_DUPREQ, "ref shared UDP DRC");
		drc = &(drc_st->udp_drc);
		DRC_ST_LOCK();
		(void)nfs_dupreq_ref_drc(drc);
		DRC_ST_UNLOCK();
		goto out;
	case DRC_TCP_V4:
	case DRC_TCP_V3:
		/* Idempotent address, no need for lock;
		 * xprt will be valid as long as svc_req.
		 */
		drc = (drc_t *)req->rq_xprt->xp_u2;
		if (drc) {
			/* found, no danger of removal */
			LogFullDebug(COMPONENT_DUPREQ, "ref DRC=%p for xprt=%p",
				     drc, req->rq_xprt);
			PTHREAD_MUTEX_lock(&drc->mtx);	/* LOCKED */
		} else {
			drc_t drc_k;
			struct rbtree_x_part *t = NULL;
			struct opr_rbtree_node *ndrc = NULL;
			drc_t *tdrc = NULL;

			memset(&drc_k, 0, sizeof(drc_k));
			drc_k.type = dtype;

			/* Since the drc can last longer than the xprt,
			 * copy the address. Read operation of constant data,
			 * no xprt lock required.
			 */
			(void)copy_xprt_addr(&drc_k.d_u.tcp.addr, req->rq_xprt);

			drc_k.d_u.tcp.hk =
			    CityHash64WithSeed((char *)&drc_k.d_u.tcp.addr,
					       sizeof(sockaddr_t), 911);
			{
				char str[SOCK_NAME_MAX];

				sprint_sockaddr(&drc_k.d_u.tcp.addr,
						str, sizeof(str));
				LogFullDebug(COMPONENT_DUPREQ,
					     "get drc for addr: %s", str);
			}

			t = rbtx_partition_of_scalar(&drc_st->tcp_drc_recycle_t,
						     drc_k.d_u.tcp.hk);
			DRC_ST_LOCK();
			ndrc =
			    opr_rbtree_lookup(&t->t, &drc_k.d_u.tcp.recycle_k);
			if (ndrc) {
				/* reuse old DRC */
				tdrc =
				    opr_containerof(ndrc, drc_t,
						    d_u.tcp.recycle_k);
				PTHREAD_MUTEX_lock(&tdrc->mtx);	/* LOCKED */
				if (tdrc->flags & DRC_FLAG_RECYCLE) {
					TAILQ_REMOVE(&drc_st->tcp_drc_recycle_q,
						     tdrc, d_u.tcp.recycle_q);
					--(drc_st->tcp_drc_recycle_qlen);
					tdrc->flags &= ~DRC_FLAG_RECYCLE;
				}
				drc = tdrc;
				LogFullDebug(COMPONENT_DUPREQ,
					     "recycle TCP DRC=%p for xprt=%p",
					     tdrc, req->rq_xprt);
			}
			if (!drc) {
				drc = alloc_tcp_drc(dtype);
				LogFullDebug(COMPONENT_DUPREQ,
					     "alloc new TCP DRC=%p for xprt=%p",
					     drc, req->rq_xprt);
				/* assign addr */
				memcpy(&drc->d_u.tcp.addr, &drc_k.d_u.tcp.addr,
				       sizeof(sockaddr_t));
				/* assign already-computed hash */
				drc->d_u.tcp.hk = drc_k.d_u.tcp.hk;
				PTHREAD_MUTEX_lock(&drc->mtx);	/* LOCKED */
				/* xprt ref */
				drc->refcnt = 1;
				/* insert dict */
				opr_rbtree_insert(&t->t,
						  &drc->d_u.tcp.recycle_k);
			}
			DRC_ST_UNLOCK();
			drc->d_u.tcp.recycle_time = 0;

			(void)nfs_dupreq_ref_drc(drc);	/* xprt ref */

			/* try to expire unused DRCs somewhat in proportion to
			 * new connection arrivals */
			drc_check_expired = true;

			LogFullDebug(COMPONENT_DUPREQ,
				     "after ref drc %p refcnt==%u ", drc,
				     drc->refcnt);

			/* Idempotent address, no need for lock;
			 * set once here, never changes.
			 * No other fields are modified.
			 * Assumes address stores are atomic.
			 */
			req->rq_xprt->xp_u2 = (void *)drc;
		}
		break;
	default:
		/* XXX error */
		break;
	}

	/* call path ref */
	(void)nfs_dupreq_ref_drc(drc);
	PTHREAD_MUTEX_unlock(&drc->mtx);

	if (drc_check_expired)
		drc_free_expired();

out:
	return drc;
}
Пример #5
0
void process_batch(struct ndn_name *name_lo, int *dst_ports,
                   struct ndn_bucket *ht)
{
	char *name[BATCH_SIZE];
	int i[BATCH_SIZE];
	int c_i[BATCH_SIZE];
	int bkt_2[BATCH_SIZE];
	int bkt_1[BATCH_SIZE];
	int bkt_num[BATCH_SIZE];
	int terminate[BATCH_SIZE];
	int prefix_match_found[BATCH_SIZE];
	uint64_t prefix_hash[BATCH_SIZE];
	uint16_t tag[BATCH_SIZE];
	struct ndn_slot *slots[BATCH_SIZE];
	int8_t _dst_port[BATCH_SIZE];
	uint64_t _hash[BATCH_SIZE];

	int I = 0;			// batch index
	void *batch_rips[BATCH_SIZE];		// goto targets
	int iMask = 0;		// No packet is done yet

	int temp_index;
	for(temp_index = 0; temp_index < BATCH_SIZE; temp_index ++) {
		batch_rips[temp_index] = &&fpp_start;
	}

fpp_start:

        name[I] = name_lo[I].name;
        FPP_PSS(name[I], fpp_label_1);
fpp_label_1:

         /**< URL char iterator and slot iterator */
        
        terminate[I] = 0;          /**< Stop processing this URL? */
        prefix_match_found[I] = 0; /**< Stop this hash-table lookup ? */
        
        /**< For names that we cannot find, dst_port is -1 */
        dst_ports[I] = -1;
        
        for(c_i[I] = 0; name[I][c_i[I]] != 0; c_i[I] ++) {
            if(name[I][c_i[I]] == '/') {
                break;
            }
        }
        
        c_i[I] ++;
        for(; name[I][c_i[I]] != 0; c_i[I] ++) {
            if(name[I][c_i[I]] != '/') {
                continue;
            }
            
            prefix_hash[I] = CityHash64WithSeed(name[I], c_i[I] + 1, NDN_SEED);
            tag[I] = prefix_hash[I] >> 48;
            
            /**< name[0] -> name[c_i] is a prefix of length c_i + 1 */
            for(bkt_num[I] = 1; bkt_num[I] <= 2; bkt_num[I] ++) {
                if(bkt_num[I] == 1) {
                    bkt_1[I] = prefix_hash[I] & NDN_NUM_BKT_;
                    FPP_PSS(&ht[bkt_1[I]], fpp_label_2);
fpp_label_2:

                    slots[I] = ht[bkt_1[I]].slots;
                } else {
                    bkt_2[I] = (bkt_1[I] ^ CityHash64((char *) &tag[I], 2)) & NDN_NUM_BKT_;
                    FPP_PSS(&ht[bkt_2[I]], fpp_label_3);
fpp_label_3:

                    slots[I] = ht[bkt_2[I]].slots;
                }
                
                /**< Now, "slots" points to an ndn_bucket. Find a valid slot
                 *  with a matching tag. */
                for(i[I] = 0; i[I] < NDN_NUM_SLOTS; i[I] ++) {
                    _dst_port[I] = slots[I][i[I]].dst_port;
                    _hash[I] = slots[I][i[I]].cityhash;
                    
                    if(_dst_port[I] >= 0 && _hash[I] == prefix_hash[I]) {
                        
                        /**< Record the dst port: this may get overwritten by
                         *  longer prefix matches later */
                        dst_ports[I] = slots[I][i[I]].dst_port;
                        
                        if(slots[I][i[I]].is_terminal == 1) {
                            /**< A terminal FIB entry: we're done! */
                            terminate[I] = 1;
                        }
                        
                        prefix_match_found[I] = 1;
                        break;
                    }
                }
                
                /**< Stop the hash-table lookup for name[0 ... c_i] */
                if(prefix_match_found[I] == 1) {
                    break;
                }
            }
            
            /**< Stop processing the name if we found a terminal FIB entry */
            if(terminate[I] == 1) {
                break;
            }
        }   /**< Loop over URL characters ends here */
        
       /**< Loop over batch ends here */

fpp_end:
    batch_rips[I] = &&fpp_end;
    iMask = FPP_SET(iMask, I); 
    if(iMask == (1 << BATCH_SIZE) - 1) {
        return;
    }
    I = (I + 1) & BATCH_SIZE_;
    goto *batch_rips[I];

}
Пример #6
0
static void CityHash64_test ( const void * key, int len, uint32_t seed, void *out) {
  *(uint64*)out = CityHash64WithSeed((const char *)key,len,seed);
}
Пример #7
0
/**
 * @brief Find and reference a DRC to process the supplied svc_req.
 *
 * @param[in] req  The svc_req being processed.
 *
 * @return The ref'd DRC if sucessfully located, else NULL.
 */
static /* inline */ drc_t *
nfs_dupreq_get_drc(struct svc_req *req)
{
	enum drc_type dtype = get_drc_type(req);
	gsh_xprt_private_t *xu = (gsh_xprt_private_t *) req->rq_xprt->xp_u1;
	drc_t *drc = NULL;
	bool drc_check_expired = false;

	switch (dtype) {
	case DRC_UDP_V234:
		LogFullDebug(COMPONENT_DUPREQ, "ref shared UDP DRC");
		drc = &(drc_st->udp_drc);
		DRC_ST_LOCK();
		(void)nfs_dupreq_ref_drc(drc);
		DRC_ST_UNLOCK();
		goto out;
		break;
	case DRC_TCP_V4:
	case DRC_TCP_V3:
		pthread_mutex_lock(&req->rq_xprt->xp_lock);
		if (xu->drc) {
			drc = xu->drc;
			LogFullDebug(COMPONENT_DUPREQ, "ref DRC=%p for xprt=%p",
				     drc, req->rq_xprt);
			pthread_mutex_lock(&drc->mtx);	/* LOCKED */
		} else {
			drc_t drc_k;
			struct rbtree_x_part *t = NULL;
			struct opr_rbtree_node *ndrc = NULL;
			drc_t *tdrc = NULL;

			memset(&drc_k, 0, sizeof(drc_k));

			drc_k.type = dtype;
			(void)copy_xprt_addr(&drc_k.d_u.tcp.addr, req->rq_xprt);

			drc_k.d_u.tcp.hk =
			    CityHash64WithSeed((char *)&drc_k.d_u.tcp.addr,
					       sizeof(sockaddr_t), 911);
			{
				char str[512];
				sprint_sockaddr(&drc_k.d_u.tcp.addr, str, 512);
				LogFullDebug(COMPONENT_DUPREQ,
					     "get drc for addr: %s", str);
			}

			t = rbtx_partition_of_scalar(&drc_st->tcp_drc_recycle_t,
						     drc_k.d_u.tcp.hk);
			DRC_ST_LOCK();
			ndrc =
			    opr_rbtree_lookup(&t->t, &drc_k.d_u.tcp.recycle_k);
			if (ndrc) {
				/* reuse old DRC */
				tdrc =
				    opr_containerof(ndrc, drc_t,
						    d_u.tcp.recycle_k);
				pthread_mutex_lock(&tdrc->mtx);	/* LOCKED */
				if (tdrc->flags & DRC_FLAG_RECYCLE) {
					TAILQ_REMOVE(&drc_st->tcp_drc_recycle_q,
						     tdrc, d_u.tcp.recycle_q);
					--(drc_st->tcp_drc_recycle_qlen);
					tdrc->flags &= ~DRC_FLAG_RECYCLE;
				}
				drc = tdrc;
				LogFullDebug(COMPONENT_DUPREQ,
					     "recycle TCP DRC=%p for xprt=%p",
					     tdrc, req->rq_xprt);
			}
			if (!drc) {
				drc = alloc_tcp_drc(dtype);
				LogFullDebug(COMPONENT_DUPREQ,
					     "alloc new TCP DRC=%p for xprt=%p",
					     drc, req->rq_xprt);
				/* assign addr */
				memcpy(&drc->d_u.tcp.addr, &drc_k.d_u.tcp.addr,
				       sizeof(sockaddr_t));
				/* assign already-computed hash */
				drc->d_u.tcp.hk = drc_k.d_u.tcp.hk;
				pthread_mutex_lock(&drc->mtx);	/* LOCKED */
				/* xprt ref */
				drc->refcnt = 1;
				/* insert dict */
				opr_rbtree_insert(&t->t,
						  &drc->d_u.tcp.recycle_k);
			}
			DRC_ST_UNLOCK();
			drc->d_u.tcp.recycle_time = 0;
			/* xprt drc */
			(void)nfs_dupreq_ref_drc(drc);	/* xu ref */

			/* try to expire unused DRCs somewhat in proportion to
			 * new connection arrivals */
			drc_check_expired = true;

			LogFullDebug(COMPONENT_DUPREQ,
				     "after ref drc %p refcnt==%u ", drc,
				     drc->refcnt);

			xu->drc = drc;
		}
		pthread_mutex_unlock(&req->rq_xprt->xp_lock);
		break;
	default:
		/* XXX error */
		break;
	}

	/* call path ref */
	(void)nfs_dupreq_ref_drc(drc);
	pthread_mutex_unlock(&drc->mtx);

	if (drc_check_expired)
		drc_free_expired();

out:
	return drc;
}
Пример #8
0
	foreach(batch_index, BATCH_SIZE) {
		char *name = name_lo[batch_index].name;
		if(batch_index != BATCH_SIZE - 1) {
			__builtin_prefetch(name_lo[batch_index + 1].name, 0, 3);
		}

		int c_i, i;	/**< URL char iterator and slot iterator */
		int bkt_num, bkt_1, bkt_2;

		int terminate = 0;			/**< Stop processing this URL? */
		int prefix_match_found = 0;	/**< Stop this hash-table lookup ? */

		/**< For names that we cannot find, dst_port is -1 */
		dst_ports[batch_index] = -1;

		for(c_i = 0; name[c_i] != 0; c_i ++) {
			if(name[c_i] == '/') {
				break;
			}
		}

		c_i ++;
		for(; name[c_i] != 0; c_i ++) {
			if(name[c_i] != '/') {
				continue;
			}

			uint64_t prefix_hash = CityHash64WithSeed(name, c_i + 1, NDN_SEED);
			uint16_t tag = prefix_hash >> 48;

			struct ndn_slot *slots;

			/**< name[0] -> name[c_i] is a prefix of length c_i + 1 */
			for(bkt_num = 1; bkt_num <= 2; bkt_num ++) {
				if(bkt_num == 1) {
					bkt_1 = prefix_hash & NDN_NUM_BKT_;
					FPP_EXPENSIVE(&ht[bkt_1]);
					slots = ht[bkt_1].slots;
				} else {
					bkt_2 = (bkt_1 ^ CityHash64((char *) &tag, 2)) & NDN_NUM_BKT_;
					FPP_EXPENSIVE(&ht[bkt_2]);
					slots = ht[bkt_2].slots;
				}

				/**< Now, "slots" points to an ndn_bucket. Find a valid slot
				  *  with a matching tag. */
				for(i = 0; i < NDN_NUM_SLOTS; i ++) {
					int8_t _dst_port = slots[i].dst_port;
					uint64_t _hash = slots[i].cityhash;

					if(_dst_port >= 0 && _hash == prefix_hash) {

						/**< Record the dst port: this may get overwritten by
						  *  longer prefix matches later */
						dst_ports[batch_index] = slots[i].dst_port;

						if(slots[i].is_terminal == 1) {
							/**< A terminal FIB entry: we're done! */
							terminate = 1;
						}

						prefix_match_found = 1;
						break;
					}
				}

				/**< Stop the hash-table lookup for name[0 ... c_i] */
				if(prefix_match_found == 1) {
					break;
				}
			}

			/**< Stop processing the name if we found a terminal FIB entry */
			if(terminate == 1) {
				break;
			}
		}	/**< Loop over URL characters ends here */
	
	}	/**< Loop over batch ends here */