Example #1
0
/**
 * mem_remove
 *
 * @return 0 on success, !0 otherwise
 */
static int mem_remove(void)
{
	struct lmb_list_head *lmb_list;
	struct dr_node *lmb;
	unsigned int removable = 0;
	int rc = 0;

	lmb_list = get_lmbs(LMB_RANDOM_SORT);
	if (lmb_list == NULL) {
		say(ERROR, "Could not gather LMB (logical memory block "
				"information.\n");
		return -1;
	}

	/* Can not know which lmbs are removable by the is_removable field
	 * if AMS ballooning is active.
	 */
	if (!ams_balloon_active()) {
		/* Make sure we have enough removable memory to fulfill
		 * this request
		 */
		for (lmb = lmb_list->lmbs; lmb; lmb = lmb->next) {
			if (lmb->is_removable)
				removable++;
		}

		if (removable == 0) {
			say(ERROR, "There is not enough removable memory "
			    "available to fulfill the request.\n");
			rc = -1;
		}

		if (removable < usr_drc_count) {
			say(INFO, "Only %u LMBs are currently candidates "
					"for removal.\n", removable);
			usr_drc_count = removable;
		}
	}

	if (!rc) {
		say(DEBUG, "Attempting removal of %d LMBs\n", usr_drc_count);
		rc = remove_lmbs(lmb_list);
	}

	say(ERROR, "Removed %d of %d requested LMB(s)\n",
	    lmb_list->lmbs_modified, usr_drc_count);
	if (lmb_list->lmbs_modified < usr_drc_count)
		say(ERROR, "Unable to hotplug remove the remaining %d LMB(s)\n",
		    usr_drc_count - lmb_list->lmbs_modified);
	report_resource_count(lmb_list->lmbs_modified);

	free_lmbs(lmb_list);
	return rc;
}
Example #2
0
int
lsslot_chrp_mem(struct cmd_opts *opts)
{
	struct lmb_list_head *lmb_list;
	struct dr_node *lmb;
	struct mem_scn *scn;
	int scn_offset = strlen("/sys/devices/system/memory/memory");
	int lmb_offset = strlen(OFDT_BASE);

	lmb_list = get_lmbs(LMB_NORMAL_SORT);
	if (lmb_list == NULL || lmb_list->lmbs == NULL)
		return -1;

	
	if (lmb_list->drconf_buf) {
		print_drconf_mem(opts, lmb_list);
	} else {
		printf("lmb size: 0x%x\n", lmb_list->lmbs->lmb_size);
		printf("%-20s  %-5s  %c  %s\n", "Memory Node", "Name", 'R',
		       "Sections");
		printf("%-20s  %-5s  %c  %s\n", "-----------", "----", '-',
		       "--------");

		for (lmb = lmb_list->lmbs; lmb; lmb = lmb->next) {
			int first = 1;

			if (!lmb->is_owned)
				continue;

			if (!lmb_list->drconf_buf)
				printf("%-20s  ", &lmb->ofdt_path[lmb_offset]);

			printf("%-5s  %c ", lmb->drc_name,
			       lmb->is_removable ? 'Y' : 'N');
		
			for (scn = lmb->lmb_mem_scns; scn; scn = scn->next) {
				if (first) {
					printf(" %s",
					       &scn->sysfs_path[scn_offset]);
					first = 0;
				} else
					printf(", %s",
					       &scn->sysfs_path[scn_offset]);
			}

			printf("\n");
		}
	}

	free_lmbs(lmb_list);

	return 0;
}
Example #3
0
/**
 * mem_add
 * @brief Add memory to the partition
 *
 * @returns 0 on success, !0 otherwise
 */
static int mem_add(void)
{
	struct lmb_list_head *lmb_list;
	int rc;

	lmb_list = get_lmbs(LMB_NORMAL_SORT);
	if (lmb_list == NULL) {
		say(ERROR, "Could not gather LMB (logical memory block "
				"information.\n");
		return -1;
	}

	say(DEBUG, "Attempting to add %d LMBs\n", usr_drc_count);
	rc = add_lmbs(lmb_list);

	say(DEBUG, "Added %d of %d requested LMB(s)\n", lmb_list->lmbs_modified,
	    usr_drc_count);
	report_resource_count(lmb_list->lmbs_modified);

	free_lmbs(lmb_list);
	return rc;
}
Example #4
0
/**
 * get_lmbs
 * @brief Build a list of all possible lmbs for the system
 *
 * @param sort LMB_NORMAL_SORT or LMB_REVERSE_SORT to control sort order
 *
 * @return list of lmbs, NULL on failure
 */
struct lmb_list_head *
get_lmbs(unsigned int sort)
{
	struct lmb_list_head *lmb_list = NULL;
	struct dr_node *lmb = NULL;
	struct stat sbuf;
	char buf[DR_STR_MAX];
	int rc = 0;

	lmb_list = zalloc(sizeof(*lmb_list));
	if (lmb_list == NULL) {
		say(DEBUG, "Could not allocate LMB list head\n");
		return NULL;
	}

	lmb_list->sort = sort;

	rc = get_str_attribute("/sys/devices/system/memory",
			       "/block_size_bytes", &buf, DR_STR_MAX);
	if (rc) {
		say(DEBUG,
		    "Could not determine block size bytes for memory.\n");
		free_lmbs(lmb_list);
		return NULL;
	}

	block_sz_bytes = strtoul(buf, NULL, 16);

	/* We also need to know which lmbs are already allocated to
	 * the system and their corresponding memory sections as defined
	 * by sysfs.  Walk the device tree and update the appropriate
	 * lmb entries (and their memory sections) as we find their device
	 * tree entries.
	 */
	if (stat(DYNAMIC_RECONFIG_MEM, &sbuf)) {
		struct dr_connector *drc_list, *drc;

		drc_list = get_drc_info(OFDT_BASE);
		if (drc_list == NULL) {
			report_unknown_error(__FILE__, __LINE__);
			rc = -1;
		} else {
			/* For memory dlpar, we need a list of all
			 * posiible memory nodes for the system, initalize
			 * those here.
			 */
			for (drc = drc_list; drc; drc = drc->next) {
				if (strncmp(drc->name, "LMB", 3))
					continue;

				lmb = lmb_list_add(drc->index, lmb_list);
				if (!lmb) {
					say(ERROR, "Failed to add LMB (%x)\n",
					    drc->index);
					rc = -1;
					break;
				}

				lmb_list->lmbs_found++;
			}
		}

		say(INFO, "Maximum of %d LMBs\n", lmb_list->lmbs_found);
		rc = get_mem_node_lmbs(lmb_list);
	} else {
		/* A small hack to here to allow memory add to work in
		 * certain kernels.  Due to a bug in the kernel (see comment
		 * in acquire_lmb()) we need to get lmb info from both places.
		 * For a good kernel, the get_mem_node_lmbs routine will not
		 * update the lmb_list.
		 */
		rc = get_dynamic_reconfig_lmbs(lmb_list);
		if (! rc)
			rc = get_mem_node_lmbs(lmb_list);
	}

	if (rc) {
		free_lmbs(lmb_list);
		lmb_list = NULL;
	} else if (sort == LMB_RANDOM_SORT) {
		shuffle_lmbs(lmb_list);
	}

	return lmb_list;
}