Revision 9e7908a9 xseg/peers/user/cached.c
b/xseg/peers/user/cached.c | ||
---|---|---|
47 | 47 |
#include <xseg/protocol.h> |
48 | 48 |
#include <xtypes/xcache.h> |
49 | 49 |
|
50 |
#define MAX_ARG_LEN 12 |
|
50 | 51 |
|
51 | 52 |
/* bucket states */ |
52 | 53 |
#define INVALID 0 |
... | ... | |
59 | 60 |
(__status == VALID || __status == DIRTY || __status == WRITING) |
60 | 61 |
|
61 | 62 |
/* write policies */ |
63 |
/*FIXME: Shouldn't they be on a flag?*/ |
|
62 | 64 |
#define WRITETHROUGH 1 |
63 | 65 |
#define WRITEBACK 2 |
64 | 66 |
|
... | ... | |
82 | 84 |
}; |
83 | 85 |
|
84 | 86 |
struct cached { |
85 |
xport bportno; |
|
86 |
uint32_t cache_size; |
|
87 | 87 |
struct xcache *cache; |
88 |
uint64_t cache_size; |
|
88 | 89 |
uint64_t max_req_size; |
89 |
uint64_t object_size;
|
|
90 |
uint32_t object_size;
|
|
90 | 91 |
uint32_t bucket_size; |
91 |
uint32_t buckets_per_object; |
|
92 |
unsigned long buckets_per_object; |
|
93 |
xport bportno; |
|
92 | 94 |
int write_policy; |
93 | 95 |
//scheduler |
94 | 96 |
}; |
... | ... | |
140 | 142 |
return (*status == LOADING); |
141 | 143 |
} |
142 | 144 |
|
145 |
/* |
|
146 |
* Convert string to size in bytes. |
|
147 |
* If syntax is invalid, return 0. Values such as zero and non-integer |
|
148 |
* multiples of segment's page size should not be accepted. |
|
149 |
*/ |
|
150 |
uint64_t str2num(char *str) |
|
151 |
{ |
|
152 |
char *unit; |
|
153 |
uint64_t num; |
|
154 |
|
|
155 |
num = strtoll(str, &unit, 10); |
|
156 |
if (strlen(unit) > 1) //Invalid syntax |
|
157 |
return 0; |
|
158 |
else if (strlen(unit) < 1) //Plain number in bytes |
|
159 |
return num; |
|
160 |
|
|
161 |
switch (*unit) { |
|
162 |
case 'g': |
|
163 |
case 'G': |
|
164 |
num *= 1024; |
|
165 |
case 'm': |
|
166 |
case 'M': |
|
167 |
num *= 1024; |
|
168 |
case 'k': |
|
169 |
case 'K': |
|
170 |
num *= 1024; |
|
171 |
break; |
|
172 |
default: |
|
173 |
num = 0; |
|
174 |
} |
|
175 |
return num; |
|
176 |
} |
|
177 |
|
|
143 | 178 |
static int rw_range(struct peerd *peer, struct peer_req *pr, int action, |
144 | 179 |
uint32_t start, uint32_t end) |
145 | 180 |
{ |
... | ... | |
159 | 194 |
struct xseg *xseg = peer->xseg; |
160 | 195 |
//FIXME: Which of those for srcport? |
161 | 196 |
//xport srcport = peer->portno_start; |
197 |
//FIXME: pr->portnumber |
|
162 | 198 |
xport srcport = req_old->src_portno; |
163 | 199 |
xport dstport = cached->bportno; |
164 | 200 |
xport p; |
... | ... | |
171 | 207 |
return -1; |
172 | 208 |
} |
173 | 209 |
|
210 |
//FIXME: swap args |
|
174 | 211 |
req->size = __calculate_size(start, end, cached); |
175 | 212 |
req->offset = __calculate_offset(start, cached); |
176 | 213 |
req->op = req_old->op; |
... | ... | |
727 | 764 |
int custom_peer_init(struct peerd *peer, int argc, char *argv[]) |
728 | 765 |
{ |
729 | 766 |
int i; |
730 |
|
|
731 |
//FIXME error checks |
|
767 |
char cache_size[MAX_ARG_LEN + 1]; |
|
768 |
char bucket_size[MAX_ARG_LEN + 1]; |
|
769 |
char object_size[MAX_ARG_LEN + 1]; |
|
770 |
char max_req_size[MAX_ARG_LEN + 1]; |
|
771 |
char write_policy[MAX_ARG_LEN + 1]; |
|
772 |
long bportno; |
|
773 |
|
|
774 |
cache_size[0] = 0; |
|
775 |
bucket_size[0] = 0; |
|
776 |
object_size[0] = 0; |
|
777 |
max_req_size[0] = 0; |
|
778 |
write_policy[0] = 0; |
|
779 |
|
|
780 |
/*Allocate enough space for needed structs*/ |
|
732 | 781 |
struct cached *cached = malloc(sizeof(struct cached)); |
782 |
if (!cached) { |
|
783 |
perror("malloc"); |
|
784 |
goto fail; |
|
785 |
} |
|
733 | 786 |
cached->cache = malloc(sizeof(struct xcache)); |
734 |
xcache_init(cached->cache, cached->cache_size, &c_ops, peer); |
|
735 |
|
|
787 |
if (!cached->cache) { |
|
788 |
perror("malloc"); |
|
789 |
goto cache_fail; |
|
790 |
} |
|
736 | 791 |
peer->priv = cached; |
737 | 792 |
|
738 | 793 |
for (i = 0; i < peer->nr_ops; i++) { |
739 | 794 |
struct cache_io *cio = malloc(sizeof(struct cache_io)); |
795 |
if (!cio) { |
|
796 |
perror("malloc"); |
|
797 |
goto cio_fail; |
|
798 |
} |
|
740 | 799 |
cio->h = NoEntry; |
741 | 800 |
cio->pending_reqs = 0; |
742 | 801 |
peer->peer_reqs[i].priv = cio; |
743 | 802 |
} |
744 | 803 |
|
804 |
/*Read arguments*/ |
|
805 |
BEGIN_READ_ARGS(argc, argv); |
|
806 |
READ_ARG_ULONG("-bp", bportno); |
|
807 |
READ_ARG_STRING("-cs", cache_size, MAX_ARG_LEN); |
|
808 |
READ_ARG_STRING("-mrs", max_req_size, MAX_ARG_LEN); |
|
809 |
READ_ARG_STRING("-os", object_size, MAX_ARG_LEN); |
|
810 |
READ_ARG_STRING("-bs", bucket_size, MAX_ARG_LEN); |
|
811 |
READ_ARG_STRING("-wcp", write_policy, MAX_ARG_LEN); |
|
812 |
END_READ_ARGS(); |
|
813 |
|
|
814 |
/*Parse arguments for:*/ |
|
815 |
|
|
816 |
/*Bucket size*/ |
|
817 |
if (!bucket_size[0]) { |
|
818 |
cached->bucket_size = BUCKET_SIZE_QUANTUM; /*Default value*/ |
|
819 |
} else { |
|
820 |
cached->bucket_size = str2num(bucket_size); |
|
821 |
if (!cached->bucket_size) { |
|
822 |
XSEGLOG2(&lc, E, "Invalid syntax: -bs %s\n", bucket_size); |
|
823 |
goto arg_fail; |
|
824 |
} |
|
825 |
if (cached->bucket_size % BUCKET_SIZE_QUANTUM) { |
|
826 |
XSEGLOG2(&lc, E, "Misaligned bucket size: %s\n", bucket_size); |
|
827 |
goto arg_fail; |
|
828 |
} |
|
829 |
} |
|
830 |
|
|
831 |
/*Object size*/ |
|
832 |
if (!object_size[0]) |
|
833 |
strcpy(object_size, "4M"); /*Default value*/ |
|
745 | 834 |
|
746 |
uint32_t cache_size; |
|
747 |
unsigned long bucket_size; |
|
748 |
unsigned long object_size; |
|
749 |
unsigned long max_req_size; |
|
835 |
cached->object_size = str2num(object_size); |
|
836 |
if (!cached->object_size) { |
|
837 |
XSEGLOG2(&lc, E, "Invalid syntax: -os %s\n", object_size); |
|
838 |
goto arg_fail; |
|
839 |
} |
|
840 |
if (cached->object_size % cached->bucket_size) { |
|
841 |
XSEGLOG2(&lc, E, "Misaligned object size: %s\n", object_size); |
|
842 |
goto arg_fail; |
|
843 |
} |
|
750 | 844 |
|
751 |
cached->bportno = -1; |
|
752 |
cached->cache_size = -1; |
|
753 |
cached->max_req_size = -1; |
|
754 |
cached->object_size = -1; |
|
755 |
cached->bucket_size = -1; |
|
756 |
cached->write_policy = WRITETHROUGH; |
|
845 |
/*Max request size*/ |
|
846 |
if (!max_req_size[0]) { |
|
847 |
XSEGLOG2(&lc, E, "Maximum request size must be provided\n"); |
|
848 |
goto arg_fail; |
|
849 |
} |
|
850 |
cached->max_req_size = str2num(max_req_size); |
|
851 |
if (!cached->max_req_size) { |
|
852 |
XSEGLOG2(&lc, E, "Invalid syntax: -mrs %s\n", max_req_size); |
|
853 |
goto arg_fail; |
|
854 |
} |
|
855 |
if (cached->max_req_size % BUCKET_SIZE_QUANTUM) { |
|
856 |
XSEGLOG2(&lc, E, "Misaligned maximum request size: %s\n", |
|
857 |
max_req_size); |
|
858 |
goto arg_fail; |
|
859 |
} |
|
757 | 860 |
|
758 |
BEGIN_READ_ARGS(argc, argv); |
|
759 |
READ_ARG_ULONG("-bp", cached->bportno); |
|
760 |
READ_ARG_ULONG("-cs", cached->cache_size); |
|
761 |
READ_ARG_ULONG("-mrs", max_req_size); |
|
762 |
READ_ARG_ULONG("-os", object_size); // In buckets |
|
763 |
READ_ARG_ULONG("-bs", bucket_size); // In BUCKET_SIZE_QUANTUM |
|
764 |
// READ_ARG_ULONG("-wcp", cached->write_policy); |
|
765 |
END_READ_ARGS(); |
|
766 |
cached->bucket_size = BUCKET_SIZE_QUANTUM; |
|
767 |
cached->max_req_size = 512 * 1024; |
|
768 |
cached->object_size = 4 * 1024 * 1024; |
|
769 |
if (cached->bportno == -1){ |
|
770 |
XSEGLOG2(&lc, E, "Portno for blocker must be provided"); |
|
771 |
usage(argv[0]); |
|
772 |
return -1; |
|
861 |
/*Cache size*/ |
|
862 |
if (!cache_size[0]) { |
|
863 |
XSEGLOG2(&lc, E, "Cache size must be provided\n"); |
|
864 |
goto arg_fail; |
|
865 |
} |
|
866 |
cached->cache_size = str2num(cache_size); |
|
867 |
if (!cached->cache_size) { |
|
868 |
XSEGLOG2(&lc, E, "Invalid syntax: -cs %s\n", cache_size); |
|
869 |
goto arg_fail; |
|
870 |
} |
|
871 |
if (cached->cache_size % cached->object_size) { |
|
872 |
XSEGLOG2(&lc, E, "Misaligned cache size: %s\n", cache_size); |
|
873 |
goto arg_fail; |
|
874 |
} |
|
875 |
|
|
876 |
/*Blocker port*/ |
|
877 |
if (bportno < 0){ |
|
878 |
XSEGLOG2(&lc, E, "Blocker port must be provided"); |
|
879 |
goto arg_fail; |
|
773 | 880 |
} |
881 |
cached->bportno = bportno; |
|
774 | 882 |
|
775 | 883 |
cached->buckets_per_object = cached->object_size / cached->bucket_size; |
884 |
|
|
885 |
/*Initialize xcache*/ |
|
886 |
xcache_init(cached->cache, cached->cache_size, &c_ops, peer); |
|
887 |
|
|
776 | 888 |
return 0; |
889 |
|
|
890 |
arg_fail: |
|
891 |
custom_peer_usage(); |
|
892 |
cio_fail: |
|
893 |
for (i = 0; i < peer->nr_ops && peer->peer_reqs[i].priv != NULL; i++) |
|
894 |
free(peer->peer_reqs[i].priv); |
|
895 |
free(cached->cache); |
|
896 |
cache_fail: |
|
897 |
free(cached); |
|
898 |
fail: |
|
899 |
return -1; |
|
777 | 900 |
} |
778 | 901 |
|
779 | 902 |
void custom_peer_finalize(struct peerd *peer) |
... | ... | |
786 | 909 |
void custom_peer_usage() |
787 | 910 |
{ |
788 | 911 |
fprintf(stderr, "Custom peer options: \n" |
789 |
"-bp : port for blocker\n" |
|
790 |
"-os : object size to cache\n" |
|
791 |
"-mrs : max request size (in KiB)\n" |
|
792 |
"-wcp : write cache policy\n" |
|
793 |
"-bs : bucket size (in 4K blocks)\n" |
|
912 |
" --------------------------------------------\n" |
|
913 |
" -op | None | XSEG operation [read|write|info|delete]\n" |
|
914 |
" --pattern | None | I/O pattern [seq|rand]\n" |
|
915 |
" -to | None | Total objects (not for read/write)\n" |
|
916 |
" -ts | None | Total I/O size\n" |
|
917 |
" -os | 4M | Object size\n" |
|
918 |
" -bs | 4k | Block size\n" |
|
919 |
" -dp | None | Destination port\n" |
|
920 |
" --iodepth | 1 | Number of in-flight I/O requests\n" |
|
921 |
" --verify | no | Verify written requests [no|meta|hash]\n" |
|
922 |
" --seed | None | Inititalize LFSR and target names\n" |
|
923 |
" --insanity| sane | Adjust insanity level of benchmark:\n" |
|
924 |
" | | [sane|eccentric|manic|paranoid]\n" |
|
794 | 925 |
"\n"); |
795 | 926 |
} |
Also available in: Unified diff