diff options
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_main.c')
| -rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 103 | 
1 files changed, 50 insertions, 53 deletions
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index c3b4227f48a..a05c7c7da22 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -433,7 +433,7 @@ xpc_activating(void *__partid)  	struct xpc_partition *part = &xpc_partitions[partid];  	unsigned long irq_flags; -	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); +	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);  	spin_lock_irqsave(&part->act_lock, irq_flags); @@ -544,7 +544,7 @@ xpc_notify_IRQ_handler(int irq, void *dev_id)  	short partid = (short)(u64)dev_id;  	struct xpc_partition *part = &xpc_partitions[partid]; -	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); +	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);  	if (xpc_part_ref(part)) {  		xpc_check_for_channel_activity(part); @@ -815,7 +815,7 @@ xpc_disconnect_wait(int ch_number)  	int wakeup_channel_mgr;  	/* now wait for all callouts to the caller's function to cease */ -	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { +	for (partid = 0; partid < xp_max_npartitions; partid++) {  		part = &xpc_partitions[partid];  		if (!xpc_part_ref(part)) @@ -895,7 +895,7 @@ xpc_do_exit(enum xp_retval reason)  	do {  		active_part_count = 0; -		for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { +		for (partid = 0; partid < xp_max_npartitions; partid++) {  			part = &xpc_partitions[partid];  			if (xpc_partition_disengaged(part) && @@ -956,11 +956,8 @@ xpc_do_exit(enum xp_retval reason)  	DBUG_ON(xpc_vars->heartbeating_to_mask != 0);  	if (reason == xpUnloading) { -		/* take ourselves off of the reboot_notifier_list */ -		(void)unregister_reboot_notifier(&xpc_reboot_notifier); - -		/* take ourselves off of the die_notifier list */  		(void)unregister_die_notifier(&xpc_die_notifier); +		(void)unregister_reboot_notifier(&xpc_reboot_notifier);  	}  	/* close down protections for IPI operations */ @@ -972,6 +969,7 @@ xpc_do_exit(enum xp_retval reason)  	if (xpc_sysctl)  		unregister_sysctl_table(xpc_sysctl); +	kfree(xpc_partitions);  	kfree(xpc_remote_copy_buffer_base);  } @@ -1017,7 +1015,7 @@ xpc_die_disengage(void)  	xpc_vars->heartbeating_to_mask = 0;	/* indicate we're deactivated */ -	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { +	for (partid = 0; partid < xp_max_npartitions; partid++) {  		part = &xpc_partitions[partid];  		if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part-> @@ -1053,7 +1051,8 @@ xpc_die_disengage(void)  		time = rtc_time();  		if (time >= disengage_request_timeout) { -			for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { +			for (partid = 0; partid < xp_max_npartitions; +			     partid++) {  				if (engaged & (1UL << partid)) {  					dev_info(xpc_part, "disengage from "  						 "remote partition %d timed " @@ -1132,18 +1131,26 @@ xpc_init(void)  	if (!ia64_platform_is("sn2"))  		return -ENODEV; +	snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); +	snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); +  	buf_size = max(XPC_RP_VARS_SIZE,  		       XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES);  	xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size,  							       GFP_KERNEL,  						  &xpc_remote_copy_buffer_base); -	if (xpc_remote_copy_buffer == NULL) +	if (xpc_remote_copy_buffer == NULL) { +		dev_err(xpc_part, "can't get memory for remote copy buffer\n");  		return -ENOMEM; +	} -	snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); -	snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); - -	xpc_sysctl = register_sysctl_table(xpc_sys_dir); +	xpc_partitions = kzalloc(sizeof(struct xpc_partition) * +				 xp_max_npartitions, GFP_KERNEL); +	if (xpc_partitions == NULL) { +		dev_err(xpc_part, "can't get memory for partition structure\n"); +		ret = -ENOMEM; +		goto out_1; +	}  	/*  	 * The first few fields of each entry of xpc_partitions[] need to @@ -1153,7 +1160,7 @@ xpc_init(void)  	 * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING  	 * PARTITION HAS BEEN ACTIVATED.  	 */ -	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { +	for (partid = 0; partid < xp_max_npartitions; partid++) {  		part = &xpc_partitions[partid];  		DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part)); @@ -1173,6 +1180,8 @@ xpc_init(void)  		atomic_set(&part->references, 0);  	} +	xpc_sysctl = register_sysctl_table(xpc_sys_dir); +  	/*  	 * Open up protections for IPI operations (and AMO operations on  	 * Shub 1.1 systems). @@ -1196,14 +1205,8 @@ xpc_init(void)  	if (ret != 0) {  		dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "  			"errno=%d\n", -ret); - -		xpc_restrict_IPI_ops(); - -		if (xpc_sysctl) -			unregister_sysctl_table(xpc_sysctl); - -		kfree(xpc_remote_copy_buffer_base); -		return -EBUSY; +		ret = -EBUSY; +		goto out_2;  	}  	/* @@ -1213,16 +1216,9 @@ xpc_init(void)  	 */  	xpc_rsvd_page = xpc_rsvd_page_init();  	if (xpc_rsvd_page == NULL) { -		dev_err(xpc_part, "could not setup our reserved page\n"); - -		free_irq(SGI_XPC_ACTIVATE, NULL); -		xpc_restrict_IPI_ops(); - -		if (xpc_sysctl) -			unregister_sysctl_table(xpc_sysctl); - -		kfree(xpc_remote_copy_buffer_base); -		return -EBUSY; +		dev_err(xpc_part, "can't setup our reserved page\n"); +		ret = -EBUSY; +		goto out_3;  	}  	/* add ourselves to the reboot_notifier_list */ @@ -1245,25 +1241,8 @@ xpc_init(void)  	kthread = kthread_run(xpc_hb_checker, NULL, XPC_HB_CHECK_THREAD_NAME);  	if (IS_ERR(kthread)) {  		dev_err(xpc_part, "failed while forking hb check thread\n"); - -		/* indicate to others that our reserved page is uninitialized */ -		xpc_rsvd_page->vars_pa = 0; - -		/* take ourselves off of the reboot_notifier_list */ -		(void)unregister_reboot_notifier(&xpc_reboot_notifier); - -		/* take ourselves off of the die_notifier list */ -		(void)unregister_die_notifier(&xpc_die_notifier); - -		del_timer_sync(&xpc_hb_timer); -		free_irq(SGI_XPC_ACTIVATE, NULL); -		xpc_restrict_IPI_ops(); - -		if (xpc_sysctl) -			unregister_sysctl_table(xpc_sysctl); - -		kfree(xpc_remote_copy_buffer_base); -		return -EBUSY; +		ret = -EBUSY; +		goto out_4;  	}  	/* @@ -1290,6 +1269,24 @@ xpc_init(void)  			  xpc_initiate_partid_to_nasids);  	return 0; + +	/* initialization was not successful */ +out_4: +	/* indicate to others that our reserved page is uninitialized */ +	xpc_rsvd_page->vars_pa = 0; +	del_timer_sync(&xpc_hb_timer); +	(void)unregister_die_notifier(&xpc_die_notifier); +	(void)unregister_reboot_notifier(&xpc_reboot_notifier); +out_3: +	free_irq(SGI_XPC_ACTIVATE, NULL); +out_2: +	xpc_restrict_IPI_ops(); +	if (xpc_sysctl) +		unregister_sysctl_table(xpc_sysctl); +	kfree(xpc_partitions); +out_1: +	kfree(xpc_remote_copy_buffer_base); +	return ret;  }  module_init(xpc_init);  |